Skip to content

Commit

Permalink
fix: handle user functions in typings
Browse files Browse the repository at this point in the history
  • Loading branch information
Rebecca Stevens committed Nov 10, 2020
1 parent 89eea43 commit 24b9aa9
Showing 1 changed file with 70 additions and 21 deletions.
91 changes: 70 additions & 21 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,34 +46,63 @@ type DeepMergeObjectProps<
Options extends deepmerge.Options
> = FlatternAlias<
{
-readonly [K in keyof T1]: Options["customMerge"] extends undefined
? DeepMerge<ValueOfKey<T1, K>, ValueOfKey<T2, K>, Options>
: ReturnType<NonNullable<Options["customMerge"]>> extends undefined
? DeepMerge<ValueOfKey<T1, K>, ValueOfKey<T2, K>, Options>
: ReturnType<
NonNullable<ReturnType<NonNullable<Options["customMerge"]>>>
>;
-readonly [K in keyof T1]: DeepMergeProps<
ValueOfKey<T1, K>,
ValueOfKey<T2, K>,
Options
>;
} &
{
-readonly [K in keyof T2]: Options["customMerge"] extends undefined
? DeepMerge<ValueOfKey<T1, K>, ValueOfKey<T2, K>, Options>
: ReturnType<NonNullable<Options["customMerge"]>> extends undefined
? DeepMerge<ValueOfKey<T1, K>, ValueOfKey<T2, K>, Options>
: ReturnType<
NonNullable<ReturnType<NonNullable<Options["customMerge"]>>>
>;
-readonly [K in keyof T2]: DeepMergeProps<
ValueOfKey<T1, K>,
ValueOfKey<T2, K>,
Options
>;
}
>;

type DeepMergeProps<T1, T2, Options extends deepmerge.Options> = GetOption<
Options,
"isMergeableObject"
> extends undefined
? GetOption<Options, "customMerge"> extends undefined
? DeepMerge<T1, T2, Options>
: DeepMergePropsCustom<T1, T2, Options>
: MergeMaybeLeafs<T1, T2, Options>;

type DeepMergePropsCustom<
T1,
T2,
Options extends deepmerge.Options
> = ReturnType<NonNullable<GetOption<Options, "customMerge">>> extends undefined
? DeepMerge<T1, T2, Options>
: undefined extends ReturnType<NonNullable<GetOption<Options, "customMerge">>>
? IsArray<T1> extends true
? IsArray<T2> extends true
? DeepMergeArrays<T1, T2, Options>
: MergeLeafs<T1, T2>
: IsArray<T2> extends true
? MergeLeafs<T1, T2>
:
| DeepMerge<T1, T2, Options>
| ReturnType<
NonNullable<
ReturnType<NonNullable<GetOption<Options, "customMerge">>>
>
>
: ReturnType<
NonNullable<ReturnType<NonNullable<GetOption<Options, "customMerge">>>>
>;

type DeepMergeArrays<
T1,
T2,
Options extends deepmerge.Options
> = T1 extends readonly [...infer E1]
? T2 extends readonly [...infer E2]
? Options["arrayMerge"] extends undefined
? GetOption<Options, "arrayMerge"> extends undefined
? [...E1, ...E2]
: ReturnType<NonNullable<Options["arrayMerge"]>>
: ReturnType<NonNullable<GetOption<Options, "arrayMerge">>>
: never
: never;

Expand All @@ -85,11 +114,24 @@ type MergeLeafs<T1, T2> = Is<T2, never> extends true
? T1
: T2;

type FlatternAlias<T> = T extends any
? {
[K in keyof T]: T[K];
}
: never;
type MergeMaybeLeafs<T1, T2, Options extends deepmerge.Options> = Is<
T2,
never
> extends true
? T1
: Is<T1, never> extends true
? T2
: Is<T2, undefined> extends true
? T1
: Is<T1, undefined> extends true
? T2
: Is<T1, object> extends false
? DeepMerge<T1, T2, Options>
: Is<T2, object> extends false
? DeepMerge<T1, T2, Options>
: unknown;

type FlatternAlias<T> = {} & { [P in keyof T]: T[P] };

type ValueOfKey<T, K> = K extends keyof T ? T[K] : never;

Expand All @@ -103,6 +145,8 @@ type IsObject<T> = Is<T, ReadonlyArray<any>> extends true
? false
: IsObjectOrArray<T>;

type IsArray<T> = Is<T, ReadonlyArray<any>>;

type ShouldMergeObjects<T1, T2> = IsObject<T1> extends true
? IsObject<T2>
: false;
Expand Down Expand Up @@ -133,6 +177,11 @@ type DefaultOptions = {
isMergeableObject: undefined;
};

type GetOption<
O extends deepmerge.Options,
K extends keyof deepmerge.Options
> = undefined extends O[K] ? DefaultOptions[K] : O[K];

/**
* Deeply merge two objects.
*
Expand Down

0 comments on commit 24b9aa9

Please sign in to comment.