diff --git a/types/index.d.ts b/types/index.d.ts index 27f2500..5b42043 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,6 +1,9 @@ // Minimum TypeScript Version: 4.2 // TODO: Can be reduce to version 4.1 upon it's release. +/** + * Deep merge 1 or more types given in an array. + */ type DeepMergeAll< Ts extends readonly [any, ...any[]], Options extends deepmerge.Options @@ -12,6 +15,9 @@ type DeepMergeAll< : T1 : never; +/** + * Deep merge 2 types. + */ type DeepMerge = IsSame< T1, T2 @@ -23,6 +29,9 @@ type DeepMerge = IsSame< : MergeLeafs : MergeLeafs; +/** + * Deep merge 2 objects (they may be arrays). + */ type DeepMergeNonPrimitive< T1, T2, @@ -31,6 +40,9 @@ type DeepMergeNonPrimitive< ? DeepMergeArrays : DeepMergeObjects; +/** + * Deep merge 2 non-array types. + */ type DeepMergeObjects< T1, T2, @@ -39,12 +51,15 @@ type DeepMergeObjects< ? DeepMergeObjectProps : MergeLeafs; -// @see https://github.com/microsoft/TypeScript/issues/41448 +/** + * Deep merge 2 non-array objects. + */ type DeepMergeObjectProps< T1, T2, Options extends deepmerge.Options > = FlatternAlias< + // @see https://github.com/microsoft/TypeScript/issues/41448 { -readonly [K in keyof T1]: DeepMergeProps< ValueOfKey, @@ -61,6 +76,10 @@ type DeepMergeObjectProps< } >; +/** + * Deep merge 2 types that are known to be properties of an object being deeply + * merged. + */ type DeepMergeProps = GetOption< Options, "isMergeableObject" @@ -70,6 +89,10 @@ type DeepMergeProps = GetOption< : DeepMergePropsCustom : MergeMaybeLeafs; +/** + * Deep merge 2 types that are known to be properties of an object being deeply + * merged and where a "customMerge" function has been provided. + */ type DeepMergePropsCustom< T1, T2, @@ -94,6 +117,9 @@ type DeepMergePropsCustom< NonNullable>>> >; +/** + * Deep merge 2 arrays. + */ type DeepMergeArrays< T1, T2, @@ -106,6 +132,9 @@ type DeepMergeArrays< : never : never; +/** + * Get the leaf type of 2 types that can't be merged. + */ type MergeLeafs = Is extends true ? T1 : Is extends true @@ -114,6 +143,9 @@ type MergeLeafs = Is extends true ? T1 : T2; +/** + * Get the leaf type of 2 types that might not be able to be merged. + */ type MergeMaybeLeafs = Is< T2, never @@ -131,36 +163,72 @@ type MergeMaybeLeafs = Is< ? DeepMerge : unknown; +/** + * Flatten a complex type such as a union or intersection of objects into a + * single object. + */ type FlatternAlias = {} & { [P in keyof T]: T[P] }; +/** + * Get the value of the given key in the given object. + */ type ValueOfKey = K extends keyof T ? T[K] : never; +/** + * Safely test whether or not the first given types extends the second. + * + * Needed in particular for testing if a type is "never". + */ type Is = [T1] extends [T2] ? true : false; +/** + * Returns whether or not the give two types are the same. + */ type IsSame = Is extends true ? Is : false; +/** + * Returns whether or not the given type an object (arrays are objects). + */ type IsObjectOrArray = Is extends true ? false : Is; -type IsObject = Is> extends true +/** + * Returns whether or not the given type a non-array object. + */ +type IsObject = IsArray extends true ? false : IsObjectOrArray; +/** + * Returns whether or not the given type an array. + */ type IsArray = Is>; +/** + * Returns whether or not 2 types are both non-array objects that can be merged. + */ type ShouldMergeObjects = IsObject extends true ? IsObject : false; -type ShouldMergeArrays = Is> extends true - ? Is> +/** + * Returns whether or not 2 types are both arrays that can be merged. + */ +type ShouldMergeArrays = IsArray extends true + ? IsArray : false; +/** + * A function that merges any 2 arrays. + */ type ArrayMerge = ( target: Array, source: Array, options: Required ) => any; +/** + * A function that merges any 2 non-arrays objects. + */ type ObjectMerge = ( key: string, options: Required @@ -168,8 +236,14 @@ type ObjectMerge = ( | ((target: any, source: any, options?: deepmerge.Options) => any) | undefined; +/** + * A function that determins if any non-array object is mergable. + */ type IsMergeable = (value: any) => boolean; +/** + * The default config options. + */ type DefaultOptions = { arrayMerge: undefined; clone: true; @@ -177,6 +251,10 @@ type DefaultOptions = { isMergeableObject: undefined; }; +/** + * Get the type of a given config option, defaulting to the default type if it + * wasn't given. + */ type GetOption< O extends deepmerge.Options, K extends keyof deepmerge.Options @@ -185,9 +263,9 @@ type GetOption< /** * Deeply merge two objects. * - * @param target the first obj - * @param source the second obj - * @param options deepmerge option + * @param target The first object. + * @param source The second object. + * @param options Deep merge options. */ declare function deepmerge< T1 extends object, @@ -196,6 +274,9 @@ declare function deepmerge< >(target: T1, source: T2, options?: Options): DeepMerge; declare namespace deepmerge { + /** + * Deep merge config options. + */ export type Options = { arrayMerge?: ArrayMerge; clone?: boolean; @@ -203,10 +284,23 @@ declare namespace deepmerge { isMergeableObject?: IsMergeable; }; + /** + * Deeply merge two or more objects. + * + * @param objects An tuple of the objects to merge. + * @param options Deep merge options. + */ export function all< Ts extends readonly [object, ...object[]], O extends Options = DefaultOptions >(objects: [...Ts], options?: O): DeepMergeAll; + + /** + * Deeply merge two or more objects. + * + * @param objects An array of the objects to merge. + * @param options Deep merge options. + */ export function all( objects: ReadonlyArray, options?: Options