Skip to content

Commit

Permalink
feat(types): add object PickShape type
Browse files Browse the repository at this point in the history
  • Loading branch information
duanwilliam committed Dec 23, 2023
1 parent f1141a1 commit 5c440db
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/types/src/object/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ import * as pick_required from "./pick-required"
export * from "./pick-required"
import * as pick_select from "./pick-select"
export * from "./pick-select"
import * as pick_shape from "./pick-shape"
export * from "./pick-shape"
import * as pick from "./pick"
export * from "./pick"
import * as properties from "./properties"
Expand Down Expand Up @@ -110,6 +112,7 @@ export default {
...pick_readonly,
...pick_required,
...pick_select,
...pick_shape,
...pick,
...properties,
...readonly_keys,
Expand Down
47 changes: 47 additions & 0 deletions packages/types/src/object/pick-shape.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { List } from "../list"
import { UnionToIntersection } from "../set"
import { IsNever, Resolve, Unreachable } from "../type"
import { KeyPaths } from "./key-paths"
import { FromPath } from "./from-path"
import { DeepGet, Key } from "."

/**
* constructs a single path
*/
type _PickPath<O, Path extends List<Key>> =
// distribute over the paths
Path extends any
// and for each one, get the corresponding value in `O` for it
? DeepGet<O, Path> extends infer V
? IsNever<V> extends false
// and construct the object from the path
? FromPath<Path, DeepGet<O, Path>>
// (dont bother with paths not in O)
: never
: Unreachable
: Unreachable

/**
* pick from O1 the keys defined in O2.
*
* does not account for property modifiers.
*
* @since 0.0.9
*
* @example
* ```ts
* type t0a = { a: { b: 0, c: 1 }, d: 4, e: 5 }
* type t0b = { a: { b: 6 }, d: 7, z: 8 }
* // { a: { b: 0; }; d: 4; }
* type e0 = PickShape<t0a, t0b>
*
* type t1a = { a: 1, b: { c: 2, d: {e: 3, f: 4 } }, g: 5, h: { i: 6, j: 7 } }
* type t1b = { a: 9, b: { d: { f: 8 } }, h: 7, z: 6 }
* // { a: 1; b: { d: { f: 4;};}; h: { i: 6; j: 7; };}
* type e1 = PickShape<t1a, t1b>
* ```
*/
export type PickShape<O1, O2> =
KeyPaths<O2> extends [infer Paths extends Key[], any]
? Resolve<UnionToIntersection<_PickPath<O1, Paths>>>
: never

0 comments on commit 5c440db

Please sign in to comment.