sindresorhus / type-fest

A collection of essential TypeScript types
Creative Commons Zero v1.0 Universal
14.09k stars 533 forks source link

MergeDeep takes type of property of source instead of using the destination type in case of undefined value #941

Open Robstei opened 1 month ago

Robstei commented 1 month ago

I am trying out remeda and came around the MergeDeep type when using the mergeDeep function from remeda.

My problem is that the MergeDeep type always uses the property type of the source value instead of using the value of the destination incase the source value is undefined.

Does this work as intended or is this a bug?

stackblitz

import { MergeDeep } from 'type-fest';

type Person = { name: string; age: number };

type PartialPerson = Partial<Person>;

// type of MergeDeepPersonPartialFirst makes sense, since all Person values will be used
type MergeDeepPersonPartialFirst = MergeDeep<PartialPerson, Person>;

// I assumed this would be inferred as the same type as MergeDeepPersonPartialLast
// but it gets infered as
// {
//   name?: string | undefined;
//   age?: number | undefined;
// }
type MergeDeepPersonPartialLast = MergeDeep<Person, PartialPerson>;

const person: Person = { name: 'a', age: 25 };
const partialPerson: PartialPerson = { name: 'b' };

// both values get inferred as
// {
//    name: string;
//    age: number;
// }
// equivalent to Person
const spreadPartialLast = { ...person, ...partialPerson };
const spreadPartiaFirst = { ...partialPerson, ...person };

// on a sideonde
// these get infered as string
type test1 = string & (string | undefined);
type test2 = (string | undefined) & string;

// these get infered as something equivalent to Person
type test3 = Partial<Person> & Person;
type test4 = Person & Partial<Person>;

Thanks for the your time

Upvote & Fund

Fund with Polar

Emiyaaaaa commented 1 month ago

I think this is a bug