Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: denoland/setup-deno@v1
with:
deno-version: ${{ env.DENO_VERSION }}
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: "https://registry.npmjs.org"
Expand Down
18 changes: 12 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v1
with:
deno-version: ${{ env.DENO_VERSION }}
Expand All @@ -31,19 +31,25 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v1
with:
deno-version: ${{ env.DENO_VERSION }}
- name: Test
run: |
deno task test
deno task test:coverage
timeout-minutes: 5
- run: |
deno task coverage --lcov > coverage.lcov
- uses: codecov/codecov-action@v3
with:
os: ${{ runner.os }}
files: ./coverage.lcov

bench:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v1
with:
deno-version: ${{ env.DENO_VERSION }}
Expand All @@ -55,11 +61,11 @@ jobs:
build-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v1
with:
deno-version: ${{ env.DENO_VERSION }}
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: "https://registry.npmjs.org"
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/npm
/docs
deno.lock
.coverage
64 changes: 47 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/unknownutil/mod.ts)
[![Test](https://github.com/lambdalisue/deno-unknownutil/workflows/Test/badge.svg)](https://github.com/lambdalisue/deno-unknownutil/actions?query=workflow%3ATest)
[![npm version](https://badge.fury.io/js/unknownutil.svg)](https://badge.fury.io/js/unknownutil)
[![codecov](https://codecov.io/github/lambdalisue/deno-unknownutil/graph/badge.svg?token=pfbLRGU5AM)](https://codecov.io/github/lambdalisue/deno-unknownutil)

A utility pack for handling `unknown` type.

Expand All @@ -15,14 +16,14 @@ A utility pack for handling `unknown` type.
It provides `is` module for type predicate functions and `assert`, `ensure`, and
`maybe` helper functions.

### is*
### is\*

Type predicate function is a function which returns `true` if a given value is
expected type. For example, `isString` (or `is.String`) returns `true` if a
given value is `string`.

```typescript
import { is } from "./mod.ts";
import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";

const a: unknown = "Hello";
if (is.String(a)) {
Expand All @@ -34,29 +35,31 @@ Additionally, `is*Of` (or `is.*Of`) functions return type predicate functions to
predicate types of `x` more precisely like:

```typescript
import { is, PredicateType } from "./mod.ts";
import {
is,
PredicateType,
} from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";

const isArticle = is.ObjectOf({
title: is.String,
body: is.String,
refs: is.ArrayOf(is.OneOf([
is.String,
is.ObjectOf({
name: is.String,
url: is.String,
}),
])),
refs: is.ArrayOf(
is.OneOf([
is.String,
is.ObjectOf({
name: is.String,
url: is.String,
}),
]),
),
});

type Article = PredicateType<typeof isArticle>;

const a: unknown = {
title: "Awesome article",
body: "This is an awesome article",
refs: [
{ name: "Deno", url: "https://deno.land/" },
"https://github.com",
],
refs: [{ name: "Deno", url: "https://deno.land/" }, "https://github.com"],
};
if (isArticle(a)) {
// a is narrowed to the type of `isArticle`
Expand All @@ -79,7 +82,10 @@ The `assert` function does nothing if a given value is expected type. Otherwise,
it throws an `AssertError` exception like:

```typescript
import { assert, is } from "./mod.ts";
import {
assert,
is,
} from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";

const a: unknown = "Hello";

Expand All @@ -97,7 +103,10 @@ The `ensure` function return the value as-is if a given value is expected type.
Otherwise, it throws an `AssertError` exception like:

```typescript
import { ensure, is } from "./mod.ts";
import {
ensure,
is,
} from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";

const a: unknown = "Hello";

Expand All @@ -116,14 +125,35 @@ Otherwise, it returns `undefined` that suites with
like:

```typescript
import { is, maybe } from "./mod.ts";
import {
is,
maybe,
} from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";

const a: unknown = "Hello";

// `maybe` returns `string | undefined` so it suites with `??`
const _: string = maybe(a, is.String) ?? "default value";
```

## Node.js (npm)

To use `unknownutil` in [Node.js][nodejs], install `unknownutil` like

```console
npm i unknownutil
```

Then import `is`, `assert`, `ensure`, and `maybe` like:

```typescript, ignore
import { assert, ensure, is, maybe } from "unknownutil";

// ...
```

[nodejs]: https://nodejs.org/

## Migration

See [GitHub Wiki](https://github.com/lambdalisue/deno-unknownutil/wiki) for
Expand Down
12 changes: 9 additions & 3 deletions deno.jsonc
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
{
"lock": false,
"imports": {
"https://deno.land/x/unknownutil@$MODULE_VERSION/": "./"
},
"tasks": {
"build-npm": "deno run -A scripts/build_npm.ts $(git describe --tags --always --dirty)",
"test": "deno test --unstable -A --parallel --doc",
"check": "deno check --unstable $(find . -name '*.ts')",
"upgrade": "deno run -A https://deno.land/x/udd/main.ts $(find . -name '*.ts' -not -path '*/npm/*')"
"test": "deno test -A --parallel --shuffle --doc",
"test:coverage": "deno task test --coverage=.coverage",
"check": "deno check ./**/*.ts",
"coverage": "deno coverage .coverage --exclude=is_bench.ts",
"upgrade": "deno run -q -A https://deno.land/x/molt@0.14.2/cli.ts ./**/*.ts",
"upgrade:commit": "deno task -q upgrade --commit --prefix :package: --pre-commit=fmt"
}
}
17 changes: 9 additions & 8 deletions is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export type TupleOf<T extends readonly Predicate<unknown>[]> = {
* Return a type predicate function that returns `true` if the type of `x` is `TupleOf<T>`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const predTup = [is.Number, is.String, is.Boolean] as const;
* const a: unknown = [0, "a", true];
Expand Down Expand Up @@ -129,7 +129,7 @@ export type UniformTupleOf<
* Return a type predicate function that returns `true` if the type of `x` is `UniformTupleOf<T>`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const a: unknown = [0, 1, 2, 3, 4];
* if (is.UniformTupleOf(5)(a)) {
Expand Down Expand Up @@ -223,7 +223,7 @@ export type ObjectOf<T extends RecordOf<Predicate<unknown>>> = FlatType<
* Otherwise, the number of keys of `x` must be greater than or equal to the number of keys of `predObj`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const predObj = {
* a: is.Number,
Expand Down Expand Up @@ -310,7 +310,7 @@ export function isAsyncFunction(
* Return `true` if the type of `x` is instance of `ctor`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const a: unknown = new Date();
* if (is.InstanceOf(Date)(a)) {
Expand Down Expand Up @@ -396,7 +396,8 @@ export function isLiteralOf<T extends Primitive>(literal: T): Predicate<T> {
* Return a type predicate function that returns `true` if the type of `x` is one of literal type in `preds`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const a: unknown = "hello";
* if (is.LiteralOneOf(["hello", "world"] as const)(a)) {
* // a is narrowed to "hello" | "world"
Expand Down Expand Up @@ -424,7 +425,7 @@ export type OneOf<T> = T extends Predicate<infer U>[] ? U : never;
* Return a type predicate function that returns `true` if the type of `x` is `OneOf<T>`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const preds = [is.Number, is.String, is.Boolean];
* const a: unknown = 0;
Expand Down Expand Up @@ -457,7 +458,7 @@ export type AllOf<T> = UnionToIntersection<OneOf<T>>;
* Return a type predicate function that returns `true` if the type of `x` is `AllOf<T>`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const preds = [is.ObjectOf({ a: is.Number }), is.ObjectOf({ b: is.String })];
* const a: unknown = { a: 0, b: "a" };
Expand Down Expand Up @@ -488,7 +489,7 @@ export type OptionalPredicate<T> = Predicate<T | undefined> & {
* Return a type predicate function that returns `true` if the type of `x` is `T` or `undefined`.
*
* ```ts
* import is from "./is.ts";
* import { is } from "https://deno.land/x/unknownutil@$MODULE_VERSION/mod.ts";
*
* const a: unknown = "a";
* if (is.OptionalOf(is.String)(a)) {
Expand Down
Loading