Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

👍 Add isObjectOf modify functions (isStrictOf, isPartialOf, isPickOf, and isOmitOf) #56

Closed
wants to merge 11 commits into from
128 changes: 94 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,31 @@
[![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.
A utility pack for handling the `unknown` type.

[deno]: https://deno.land/

## Usage

It provides `is` module for type predicate functions and `assert`, `ensure`, and
`maybe` helper functions.
It provides a `is` module for type predicate functions and `assert`, `ensure`,
and `maybe` helper functions.

### 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`.
A type predicate function is a function that returns `true` if a given value is
of the expected type. For example, `isString` (or `is.String`) returns `true` if
a given value is a `string`.

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

const a: unknown = "Hello";
if (is.String(a)) {
// 'a' is 'string' in this block
// 'a' is a 'string' in this block
}
```

Additionally, `is*Of` (or `is.*Of`) functions return type predicate functions to
predicate types of `x` more precisely like:
For more complex types, you can use `is*Of` (or `is.*Of`) functions like:

```typescript
import {
Expand All @@ -52,8 +51,11 @@ const isArticle = is.ObjectOf({
}),
]),
),
createTime: is.OptionalOf(is.InstanceOf(Date)),
updateTime: is.OptionalOf(is.InstanceOf(Date)),
});

// Infer the type of `Article` from the definition of `isArticle`
type Article = PredicateType<typeof isArticle>;

const a: unknown = {
Expand All @@ -62,7 +64,7 @@ const a: unknown = {
refs: [{ name: "Deno", url: "https://deno.land/" }, "https://github.com"],
};
if (isArticle(a)) {
// a is narrowed to the type of `isArticle`
// 'a' is narrowed to the type of `isArticle`
console.log(a.title);
console.log(a.body);
for (const ref of a.refs) {
Expand All @@ -76,10 +78,83 @@ if (isArticle(a)) {
}
```

Additionally, you can manipulate the predicate function returned from
`isObjectOf` with `isPickOf`, `isOmitOf`, and `isPartialOf` similar to
TypeScript's `Pick`, `Omit`, and `Partial` utility types.

```typescript
import { is } 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,
}),
]),
),
createTime: is.OptionalOf(is.InstanceOf(Date)),
updateTime: is.OptionalOf(is.InstanceOf(Date)),
});

const isArticleCreateParams = is.PickOf(isArticle, ["title", "body", "refs"]);
// is equivalent to
//const isArticleCreateParams = is.ObjectOf({
// title: is.String,
// body: is.String,
// refs: is.ArrayOf(
// is.OneOf([
// is.String,
// is.ObjectOf({
// name: is.String,
// url: is.String,
// }),
// ]),
// ),
//});

const isArticleUpdateParams = is.OmitOf(isArticleCreateParams, ["title"]);
// is equivalent to
//const isArticleUpdateParams = is.ObjectOf({
// body: is.String,
// refs: is.ArrayOf(
// is.OneOf([
// is.String,
// is.ObjectOf({
// name: is.String,
// url: is.String,
// }),
// ]),
// ),
//});

const isArticlePatchParams = is.PartialOf(isArticleUpdateParams);
// is equivalent to
//const isArticlePatchParams = is.ObjectOf({
// body: is.Optional(is.String),
// refs: is.Optional(is.ArrayOf(
// is.OneOf([
// is.String,
// is.ObjectOf({
// name: is.String,
// url: is.String,
// }),
// ]),
// )),
//});
```

See [Deno Doc](https://doc.deno.land/https/deno.land/x/unknownutil/mod.ts) for
the list of available type predicate functions.

### assert

The `assert` function does nothing if a given value is expected type. Otherwise,
it throws an `AssertError` exception like:
The `assert` function does nothing if a given value is of the expected type.
Otherwise, it throws an `AssertError` exception like:

```typescript
import {
Expand All @@ -91,16 +166,16 @@ const a: unknown = "Hello";

// `assert` does nothing or throws an `AssertError`
assert(a, is.String);
// a is now narrowed to string
// 'a' is now narrowed to a 'string'

// With custom message
// With a custom message
assert(a, is.String, { message: "a must be a string" });
```

### ensure

The `ensure` function return the value as-is if a given value is expected type.
Otherwise, it throws an `AssertError` exception like:
The `ensure` function returns the value as-is if a given value is of the
expected type. Otherwise, it throws an `AssertError` exception like:

```typescript
import {
Expand All @@ -113,14 +188,14 @@ const a: unknown = "Hello";
// `ensure` returns `string` or throws an `AssertError`
const _: string = ensure(a, is.String);

// With custom message
// With a custom message
const __: string = ensure(a, is.String, { message: "a must be a string" });
```

### maybe

The `maybe` function return the value as-is if a given value is expected type.
Otherwise, it returns `undefined` that suites with
The `maybe` function returns the value as-is if a given value is of the expected
type. Otherwise, it returns `undefined`, which is suitable for use with the
[nullish coalescing operator (`??`)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing)
like:

Expand All @@ -129,19 +204,4 @@ 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";
```

## Migration

See [GitHub Wiki](https://github.com/lambdalisue/deno-unknownutil/wiki) for
migration to v3 from v2 or v2 from v1.

## License

The code follows MIT license written in [LICENSE](./LICENSE). Contributors need
to agree that any modifications sent in this repository follow the license.
Loading
Loading