Завдання

Об’єднайте два типи в один. Ключі другого типу замінюють ключі першого. Наприклад:

type Foo = {
  a: number;
  b: string;
};

type Bar = {
  b: number;
};

type merged = Merge<Foo, Bar>; // expected { a: number; b: number }

Розв’язок

Дане завдання дуже схоже на “append to object”. Тоді ми використовували об’єднання типів, щоб зібрати всі властивості об’єкту та рядок в один тип.

Повторюємо те саме і тут. Як результат, отримаємо об’єкт з ключами першого і другого типів.

type Merge<F, S> = { [P in keyof F | keyof S]: never };

Маючи ключі обох об’єктів, почнемо проставляти типи їх значень. Почнемо з S, тому що він може переназначити властивості типу F. Також перевіряємо наявність властивостей у типі S:

type Merge<F, S> = {
  [P in keyof F | keyof S]: P extends keyof S ? S[P] : never;
};

У випадку, коли властивість відсутня, ми перевіряємо її наявність у типі F. Якщо є, то беремо значення звідти.

type Merge<F, S> = {
  [P in keyof F | keyof S]: P extends keyof S
    ? S[P]
    : P extends keyof F
    ? F[P]
    : never;
};

Посилання