-
Notifications
You must be signed in to change notification settings - Fork 216
Open
Description
Problem
When passing two objects with different shapes, the type definitions of deepmerge can usually produce the correct return type:
const a = { foo: "foo" }
const b = { bar: "bar" };
const merged = deepmerge(a, b); // typeof merged is `{ foo: string } & { bar: string }`However, when passing to objects that share a base shape, deepmerge only returns the shape of the first object:
const a = { foo: 'foo' };
const b = { foo: 'foo', bar: 'bar' };
const merged = deepmerge(a, b); // typeof merged is `{ foo: string }`This case is not handled in test/typescript.ts
Potential solution
It seems that this happens because TypeScript is attempting to use the first clause when objects share a base shape, while it should be using the second:
declare function deepmerge<T>(x: Partial<T>, y: Partial<T>, options?: deepmerge.Options): T;
declare function deepmerge<T1, T2>(x: Partial<T1>, y: Partial<T2>, options?: deepmerge.Options): T1 & T2;I tried reordering the clauses to:
declare function deepmerge<T1, T2>(x: Partial<T1>, y: Partial<T2>, options?: deepmerge.Options): T1 & T2;
declare function deepmerge<T>(x: Partial<T>, y: Partial<T>, options?: deepmerge.Options): T;And it solves the issue, but then it never seems to use the second clause, even if both objects are the same shape, producing a return type more complex than before:
const a = { foo: 'a' };
const b = { foo: 'b' };
const merged = deepmerge(a, b); // typeof merged is `{ foo: string } & { foo: string }`
// previously it'd be just `{ foo: string }`Not sure if that's ok.
Would it be acceptable to get rid of the deepmerge<T> type clause and use just <T1, T2>?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels