Skip to content

Commit c0674dd

Browse files
committed
First impl
1 parent 1cf1345 commit c0674dd

File tree

9 files changed

+627
-0
lines changed

9 files changed

+627
-0
lines changed

.github/workflows/test.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Test
2+
3+
env:
4+
DENO_VERSION: 1.x
5+
6+
on:
7+
schedule:
8+
- cron: "0 7 * * 0"
9+
push:
10+
branches:
11+
- main
12+
pull_request:
13+
branches:
14+
- main
15+
16+
jobs:
17+
lint:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v2
21+
- uses: denoland/setup-deno@main
22+
with:
23+
deno-version: ${{ env.DENO_VERSION }}
24+
- name: Lint
25+
run: deno lint
26+
27+
format:
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v2
31+
- uses: denoland/setup-deno@main
32+
with:
33+
deno-version: ${{ env.DENO_VERSION }}
34+
- name: Format
35+
run: |
36+
deno fmt --check
37+
38+
test:
39+
runs-on: ubuntu-latest
40+
steps:
41+
- uses: actions/checkout@v2
42+
- uses: denoland/setup-deno@main
43+
with:
44+
deno-version: ${{ env.DENO_VERSION }}
45+
- name: Test
46+
run: |
47+
deno test
48+
timeout-minutes: 5
49+
50+
typecheck:
51+
runs-on: ubuntu-latest
52+
steps:
53+
- uses: actions/checkout@v2
54+
- uses: denoland/setup-deno@main
55+
with:
56+
deno-version: ${{ env.DENO_VERSION }}
57+
- name: Type check
58+
run: |
59+
deno test --unstable --no-run ./*.ts

LICENSE

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright 2021 Alisue, hashnote.net
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.
20+

README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# unknownutil-deno
2+
3+
[![deno land](http://img.shields.io/badge/available%20on-deno.land/x-lightgrey.svg?logo=deno)](https://deno.land/x/unknownutil)
4+
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/unknownutil/mod.ts)
5+
[![Test](https://github.com/lambdalisue/unknownutil-deno/workflows/Test/badge.svg)](https://github.com/lambdalisue/unknownutil-deno/actions?query=workflow%3ATest)
6+
7+
A utility pack for handling `unknown` type.
8+
9+
[deno]: https://deno.land/
10+
11+
## Usage
12+
13+
### isXXXXX
14+
15+
The `unknownutil` provides the following predicate functions
16+
17+
- `isString(x: unknown): x is string`
18+
- `isNumber(x: unknown): x is number`
19+
- `isArray<T extends unknown>(x: unknown, pred?: Predicate<T>): x is T[]`
20+
- `isObject<T extends unknown>(x: unknown, pred?: Predicate<T>): x is Record<string, T>`
21+
- `isFunction(x: unknown): x is (...args: unknown[]) => unknown`
22+
- `isNull(x: unknown): x is null`
23+
- `isUndefined(x: unknown): x is undefined`
24+
- `isNone(x: unknown): x is null | undefined`
25+
26+
For example:
27+
28+
```typescript
29+
import { isString } from "https://deno.land/x/unknownutil/mod.ts";
30+
31+
const a: unknown = "Hello";
32+
33+
if (isString(a)) {
34+
// 'a' is 'string' in this block
35+
}
36+
```
37+
38+
Additionally, `isArray` and `isObject` supports an inner predicate function to
39+
predicate `x` more precisely like:
40+
41+
```typescript
42+
import { isArray, isString } from "https://deno.land/x/unknownutil/mod.ts";
43+
44+
const a: unknown = ["a", "b", "c"];
45+
46+
if (isArray(a)) {
47+
// 'a' is 'unknown[]' in this block
48+
}
49+
50+
if (isArray(a, isString)) {
51+
// 'a' is 'string[]' in this block
52+
}
53+
```
54+
55+
### ensureXXXXX
56+
57+
The `unknownutil` provides the following ensure functions which will raise
58+
`EnsureError` when a given `x` is not expected type.
59+
60+
- `ensureString(x: unknown): assert x is string`
61+
- `ensureNumber(x: unknown): assert x is string`
62+
- `ensureArray<T extends unknown>(x: unknown, pred?: Predicate<T>): assert x is T[]`
63+
- `ensureObject<T extends unknown>(x: unknown, pred?: Predicate<T>): x ensure Record<string, T>`
64+
- `ensureFunction(x: unknown): x ensure (...args: unknown[]) => unknown`
65+
- `ensureNull(x: unknown): x ensure null`
66+
- `ensureUndefined(x: unknown): x ensure undefined`
67+
- `ensureNone(x: unknown): x ensure null | undefined`
68+
69+
For example:
70+
71+
```typescript
72+
import { ensureString } from "https://deno.land/x/unknownutil/mod.ts";
73+
74+
const a: unknown = "Hello";
75+
ensureString(a); // Now 'a' is 'string'
76+
77+
const b: unknown = 0;
78+
ensureString(b); // Raise EnsureError on above while 'b' is not string
79+
```
80+
81+
Additionally, `ensureArray` and `ensureObject` supports an inner predicate
82+
function to predicate `x` more precisely like:
83+
84+
```typescript
85+
import { ensureArray, isString } from "https://deno.land/x/unknownutil/mod.ts";
86+
87+
const a: unknown = ["a", "b", "c"];
88+
ensureArray(a); // Now 'a' is 'unknown[]'
89+
ensureArray(a, isString); // Now 'a' is 'string[]'
90+
91+
const b: unknown = [0, 1, 2];
92+
ensureArray(b); // Now 'b' is 'unknown[]'
93+
ensureArray(b, isString); // Raise EnsureError on above while 'b' is not string array
94+
```
95+
96+
## License
97+
98+
The code follows MIT license written in [LICENSE](./LICENSE). Contributors need
99+
to agree that any modifications sent in this repository follow the license.

deps_test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "https://deno.land/[email protected]/testing/asserts.ts";

ensure.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import {
2+
isArray,
3+
isFunction,
4+
isNone,
5+
isNull,
6+
isNumber,
7+
isObject,
8+
isString,
9+
isUndefined,
10+
Predicate,
11+
} from "./is.ts";
12+
13+
export class EnsureError extends Error {
14+
constructor(message?: string) {
15+
super(message);
16+
17+
if (Error.captureStackTrace) {
18+
Error.captureStackTrace(this, EnsureError);
19+
}
20+
21+
this.name = "EnsureError";
22+
}
23+
}
24+
25+
/**
26+
* Ensure if `x` is expected type by raising an `EnsureError` when it's not.
27+
*/
28+
export function ensure<T>(
29+
x: unknown,
30+
pred: Predicate<T>,
31+
message = "The value is not expected type",
32+
): asserts x is T {
33+
if (!pred(x)) {
34+
throw new EnsureError(message);
35+
}
36+
}
37+
38+
/**
39+
* Ensure if `x` is string by raising an `EnsureError` when it's not.
40+
*/
41+
export function ensureString(x: unknown): asserts x is string {
42+
return ensure(x, isString, "The value must be string");
43+
}
44+
45+
/**
46+
* Ensure if `x` is number by raising an `EnsureError` when it's not.
47+
*/
48+
export function ensureNumber(x: unknown): asserts x is number {
49+
return ensure(x, isNumber, "The value must be number");
50+
}
51+
52+
/**
53+
* Ensure if `x` is array by raising an `EnsureError` when it's not.
54+
*/
55+
export function ensureArray<T extends unknown>(
56+
x: unknown,
57+
ipred?: Predicate<T>,
58+
): asserts x is T[] {
59+
const pred = (x: unknown): x is T[] => isArray(x, ipred);
60+
return ensure(x, pred, "The value must be array");
61+
}
62+
63+
/**
64+
* Ensure if `x` is object by raising an `EnsureError` when it's not.
65+
*/
66+
export function ensureObject<T>(
67+
x: unknown,
68+
ipred?: Predicate<T>,
69+
): asserts x is Record<string, T> {
70+
const pred = (x: unknown): x is Record<string, T> => isObject(x, ipred);
71+
return ensure(x, pred, "The value must be object");
72+
}
73+
74+
/**
75+
* Ensure if `x` is function by raising an `EnsureError` when it's not.
76+
*/
77+
export function ensureFunction(
78+
x: unknown,
79+
): asserts x is (...args: unknown[]) => unknown {
80+
return ensure(x, isFunction, "The value must be function");
81+
}
82+
83+
/**
84+
* Ensure if `x` is null by raising an `EnsureError` when it's not.
85+
*/
86+
export function ensureNull(x: unknown): asserts x is null {
87+
return ensure(x, isNull, "The value must be null");
88+
}
89+
90+
/**
91+
* Ensure if `x` is undefined by raising an `EnsureError` when it's not.
92+
*/
93+
export function ensureUndefined(x: unknown): asserts x is undefined {
94+
return ensure(x, isUndefined, "The value must be undefined");
95+
}
96+
97+
/**
98+
* Ensure if `x` is null or undefined by raising an `EnsureError` when it's not.
99+
*/
100+
export function ensureNone(x: unknown): asserts x is null | undefined {
101+
return ensure(x, isNone, "The value must be null or undefined");
102+
}

0 commit comments

Comments
 (0)