type-fest icon indicating copy to clipboard operation
type-fest copied to clipboard

[MergeDeep] No attempt merge on Destination + Source types

Open bombillazo opened this issue 1 year ago • 8 comments

Hello, I was looking at the MergeDeep type definitions since we have a use case that requires a specific behavior for MergeDeep:

Given:

MergeDeep<Destination, Source, Options extends MergeDeepOptions = {}>

I would like to know: if the key is present in both Destination and Source types, is it possible to completely ignore the Destination type and use the incoming Source type instead of attempting to merge?

If not, it would be great to add a new option to MergeDeepOptions so that the merge behavior is to utilize the Source type completely, not merging if the key exists.

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • The funding will be given to active contributors.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar

bombillazo avatar Apr 13 '23 16:04 bombillazo

Hey @sindresorhus , any thoughts on this?

bombillazo avatar Jun 14 '23 15:06 bombillazo

I would like to know: if the key is present in both Destination and Source types

Do you mean if all keys are present in both?

sindresorhus avatar Jun 14 '23 22:06 sindresorhus

The MergeDeep type is already quite complicated, so it must be something very convincing for us to add more complication to it.

sindresorhus avatar Jun 14 '23 22:06 sindresorhus

What I mean is having the option to keep the type of either source or destination key types. At the moment, the behavior is to attempt to merge every on of each key type. So for simplicity's sake, we have the following:

type Source = {
  a: string;
  b: number;
  d: string | null;
}

type Destination = {
  a: boolean;
  b: boolean | undefined;
  c: string;
}

The resulting merge type would be something like this:

type Merge = {
  a: string | boolean;
  b: number | boolean | undefined;
  c: string;
  d: string | null;
}

It would be nice to have the option to prioritize or "keep" the type of source or destination. In the same example, if we want to merge but maintain any types present in the source, the result would be:

type Merge = {
   a: string;
   b: number;
   c: string;
   d: string | null;
 }

bombillazo avatar Jun 15 '23 00:06 bombillazo

The use case for this is when one wants to enrich or enhance the properties of an object by only adding what it is missing from the incoming type object. This is common like when one creates a typed object with the default, minimally required data for forms or DB model that is later filled with remote or user-generated data.

bombillazo avatar Jun 15 '23 00:06 bombillazo

Pinging @skarab42 as he's the one that added the type.

sindresorhus avatar Jun 20 '23 09:06 sindresorhus

@bombillazo @sindresorhus I'm not sure I understand, because it seems to me that this is already the behavior of Merge (playground).

image

skarab42 avatar Jun 20 '23 15:06 skarab42

Ahh now I remember what it was! We want to override the types from Source if they are unknown or undefined :)

bombillazo avatar Jun 20 '23 16:06 bombillazo

I think we can close this as the use case has been worked around and I don't remember quite what I was going for, I probably solved it some other way.

bombillazo avatar Aug 12 '24 20:08 bombillazo