Skip to content

[TypeScript Bug] Return type of deepmerge(target, source) incorrectly returned in some cases #271

@guisehn

Description

@guisehn

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>?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions