UNPKG

froebel

Version:
33 lines (32 loc) 2.19 kB
import { Mutable as Mutable_, OptionalKeys, Primitive, RequiredKeys } from "./types"; /** * Recursively merges `A` and `B`. If a property in `A` and `B` is of a * different type (i.e. it's not an array, Set, Map, or plain object in both, * the value from `B` will be used in the result). * * If there are self-references in the cloned values, array / Set items, or Map * keys or values, they will also be self-referencing in the result. */ declare const merge: <A, B>(a: A, b: B) => Merge<A, B>; export default merge; export declare type Merge<A, B> = A extends Primitive ? Mutable<B> : Merge_<Mutable<A>, Mutable<B>>; declare type Merge_<A, B> = Extract<B, Primitive> | MergeList<A, B> | MergeSet<A, B> | MergeMap<A, B> | MergeObject<A, B>; declare type MergeSet<A, B> = B extends Set<infer IB> ? (A extends Set<infer IA> ? Set<IA | IB> : B) : never; declare type MergeMap<A, B> = B extends Map<infer KB, infer VB> ? (A extends Map<infer KA, infer VA> ? Map<KA | KB, VA | VB> : B) : never; declare type MergeObject<A, B> = B extends Record<any, unknown> ? (A extends Record<any, unknown> ? MergeObject_<A, B> : never) : never; declare type MergeObject_<A, B> = MakeOptional<{ [K in keyof A | keyof B]: K extends keyof B ? (K extends keyof A ? (Merge<A[K], B[K]> | (K extends OptionalKeys<B> ? A[K] : never)) : B[K]) : K extends keyof A ? A[K] : never; }, Exclude<OptionalKeys<B>, RequiredKeys<A>> | Exclude<OptionalKeys<A>, RequiredKeys<B>>>; declare type MergeList<A, B> = A extends unknown[] ? (B extends unknown[] ? (B[number][] extends Required<B> ? MergeArray<A, B> : A[number][] extends Required<A> ? MergeArray<A, B> : MergeTuple<A, B>) : never) : never; declare type MergeTuple<A extends unknown[], B extends unknown[]> = B extends [ infer H, ...infer T ] ? MergeTuple<[...A, H], T> : A; declare type MergeArray<A extends unknown[], B extends unknown[]> = (A[number] | B[number])[]; declare type MakeOptional<T, O extends keyof T> = FlattenIntersection<Pick<T, Exclude<keyof T, O>> & { [K in O]?: T[K]; }>; declare type FlattenIntersection<T> = { [K in keyof T]: T[K]; }; declare type Mutable<T> = T extends Set<any> | Map<any, any> ? T : Mutable_<T>;