ghaiklor / type-challenges-solutions

Solutions for the collection of TypeScript type challenges with explanations
https://ghaiklor.github.io/type-challenges-solutions/
Creative Commons Attribution 4.0 International
470 stars 56 forks source link

type-challenges-solutions/en/medium-merge #251

Open utterances-bot opened 1 year ago

utterances-bot commented 1 year ago

Merge

This project is aimed at helping you better understand how the type system works, writing your own utilities, or just having fun with the challenges.

https://ghaiklor.github.io/type-challenges-solutions/en/medium-merge.html

zavarka commented 1 year ago

A version that is a few characters shorter - keyof F | keyof S is the same as keyof F & S. But I could be missing something. :)

type Merge<F, S> = {
  [P in keyof (F & S)]: P extends keyof S
    ? S[P]
    : P extends keyof F
    ? F[P]
    : never;
};
ghaiklor commented 1 year ago

@zavarka clever 😺 I think there could be some edge-cases with properties in a sense how they will be treated when intersecting them, but for common cases should work, yes.

dgh500 commented 1 year ago

Using a util function admittedly ( also from the 'Append to Object' challenge ) but the Collapse ( or Flatten ) just satisfies the tests - without it the solution is equivalent.

type Merge<F, S> = Collapse<S & {
  [K in keyof F as K extends keyof S ? never : K]: F[K]
}>

type Collapse<T extends { [k: string]: any }> = {
  [K in keyof T]: T[K]
}
BruceYuj commented 1 year ago

Why should we use k extends key F again because k is in keyof F | keyof S?

type Merge<F, S> = {
  [P in keyof F | keyof S]: P extends keyof S
    ? S[P]
    : F[P]
};
ghaiklor commented 1 year ago

@BruceYuj yes, because your key can be either in first set or another one, and you need to filter out one of them.