UNPKG

merge-anything

Version:

Merge objects & other types recursively. A simple & small integration.

51 lines (50 loc) 2.13 kB
import type { Iteration, IterationOf, Next, Pos } from './Iteration.js'; import type { Length, List } from './List.js'; import type { MergeDeep } from './MergeDeep.js'; /** * Ask TS to re-check that `A1` extends `A2`. * And if it fails, `A2` will be enforced anyway. * Can also be used to add constraints on parameters. * @param A1 to check against * @param A2 to cast to * @returns `A1 | A2` * @example * ```ts * type test0 = Cast<'42', string> // '42' * type test1 = Cast<'42', number> // number * ``` */ type Cast<A1, A2> = A1 extends A2 ? A1 : A2; /** * Check whether `A1` is part of `A2` or not. The difference with * `extends` is that it forces a [[Boolean]] return. * @param A1 * @param A2 * @returns [[Boolean]] * @example * ```ts * type test0 = Extends<'a' | 'b', 'b'> // Boolean * type test1 = Extends<'a', 'a' | 'b'> // True * * type test2 = Extends<{a: string}, {a: any}> // True * type test3 = Extends<{a: any}, {a: any, b: any}> // False * * type test4 = Extends<never, never> // False * /// Nothing cannot extend nothing, use `Equals` * ``` */ type Extends<A1, A2> = [A1] extends [never] ? 0 : A1 extends A2 ? 1 : 0; type __Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>, I extends Iteration = IterationOf<0>> = Extends<Pos<I>, Length<Os>> extends 1 ? O : __Assign<MergeDeep<O, Os[Pos<I>]>, Os, Next<I>>; type _Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = __Assign<O, Os> extends infer X ? Cast<X, Record<string | number | symbol, unknown>> : never; /** * Assign a list of [[Object]] into `O` with [[MergeDeep]]. Merges from right to * left, first items get overridden by the next ones (last-in overrides). * @param O to assign to * @param Os to assign * @returns [[Object]] * @example * ```ts * ``` */ export type Assign<O extends Record<string | number | symbol, unknown>, Os extends List<Record<string | number | symbol, unknown>>> = O extends unknown ? (Os extends unknown ? _Assign<O, Os> : never) : never; export {};