Skip to content

Commit

Permalink
Merge pull request #57 from lambdalisue/impl-objmodify
Browse files Browse the repository at this point in the history
👍 Add `isObjectOf` modify functions (`isReadonlyOf`, `isStrictOf`, `isRequiredOf`, `isPartialOf`, `isPickOf`, and `isOmitOf`)
  • Loading branch information
lambdalisue authored Feb 12, 2024
2 parents f38987f + a3b2679 commit 5b4795c
Show file tree
Hide file tree
Showing 19 changed files with 3,128 additions and 1,822 deletions.
116 changes: 113 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ if (is.String(a)) {
}
```

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 @@ -44,16 +43,19 @@ const isArticle = is.ObjectOf({
title: is.String,
body: is.String,
refs: is.ArrayOf(
is.OneOf([
is.UnionOf([
is.String,
is.ObjectOf({
name: is.String,
url: is.String,
}),
]),
),
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 @@ -76,6 +78,114 @@ if (isArticle(a)) {
}
```

Additionally, you can manipulate the predicate function returned from
`isObjectOf` with `isPickOf`, `isOmitOf`, `isPartialOf`, and `isRequiredOf`
similar to TypeScript's `Pick`, `Omit`, `Partial`, `Required` 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.UnionOf([
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.UnionOf([
// 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.UnionOf([
// is.String,
// is.ObjectOf({
// name: is.String,
// url: is.String,
// }),
// ]),
// ),
//});

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

const isArticleAvailableParams = is.RequiredOf(isArticle);
// is equivalent to
//const isArticlePutParams = is.ObjectOf({
// body: is.String,
// refs: is.ArrayOf(
// is.UnionOf([
// is.String,
// is.ObjectOf({
// name: is.String,
// url: is.String,
// }),
// ]),
// ),
// createTime: is.InstanceOf(Date),
// updateTime: is.InstanceOf(Date),
//});
```

If you need an union type or an intersection type, use `isUnionOf` and
`isIntersectionOf` like:

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

const isFoo = is.ObjectOf({
foo: is.String,
});

const isBar = is.ObjectOf({
bar: is.String,
});

const isFooOrBar = is.UnionOf([isFoo, isBar]);
// { foo: string } | { bar: string }

const isFooAndBar = is.IntersectionOf([isFoo, isBar]);
// { foo: string } & { bar: string }
```

### assert

The `assert` function does nothing if a given value is expected type. Otherwise,
Expand Down
10 changes: 10 additions & 0 deletions _typeutil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export type FlatType<T> = T extends Record<PropertyKey, unknown>
? { [K in keyof T]: FlatType<T[K]> }
: T;

export type UnionToIntersection<U> =
(U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void)
? I
: never;

export type Writable<T> = { -readonly [P in keyof T]: T[P] };
Loading

0 comments on commit 5b4795c

Please sign in to comment.