Diff
Завдання
Обчисліть різницю між об’єктами O
& O1
. Наприклад:
type Foo = {
name: string;
age: string;
};
type Bar = {
name: string;
age: string;
gender: number;
};
type test0 = Diff<Foo, Bar>; // expected { gender: number }
Розв’язок
Очевидно, що в нашому завданні потрібно маніпулювати об’єктами. Тому, ймовірно, типи зіставлення тут зіграють свою роль.
Почнемо з типу, в якому перебираємо об’єднання властивостей двох об’єктів. Перш ніж шукати різницю двох об’єктів, потрібно зібрати всі їх властивості.
type Diff<O, O1> = { [P in keyof O | keyof O1]: never };
Коли ми перебираємо ключі першого чи другого об’єкта, перевіряємо чи існує властивість на тому чи іншому об’єкті. Додамо умовний тип, в якому перевіримо наявність властивостей в об’єктах:
type Diff<O, O1> = {
[P in keyof O | keyof O1]: P extends keyof O
? O[P]
: P extends keyof O1
? O1[P]
: never;
};
Чудово! У нас є об’єкт, який містить в собі об’єднання двох об’єктів. Останнє, що потрібно зробити — відфільтрувати ті властивості, які існують у двох об’єктах одночасно.
Але як ми можемо знати які властивості існують у двох об’єктах? Типи перетинів!
Візьмемо перетин властивостей двох об’єктів, й виключимо типи в перетині з
нашого типу P
:
type Diff<O, O1> = {
[P in keyof O | keyof O1 as Exclude<P, keyof O & keyof O1>]: P extends keyof O
? O[P]
: P extends keyof O1
? O1[P]
: never;
};
Коментарі