PartialByKeys
Завдання
Реалізуйте загальний PartialByKeys<T, K>
, який приймає два аргументи типу T
і K
.
K
визначає набір властивостей T
, які мають бути необов’язковими. Коли K
не
надається, він має робити всі властивості необов’язковими, як звичайний
Partial<T>
.
Розв’язок
Гаразд, давайте розіб’ємо це завдання на три частини.
- Вибрати усі властивості
T
, які присутні вK
, і зробити їх необов’язковими. - Вибрати усі властивості
T
, яких немає вK
, і зберегти їх як є. - Об’єднати обидва згадані вище типи, щоб отримати рішення.
Тож, як нам створити новий тип, вибравши всі властивості з T
, крім K
?
Вірно. Ми можемо використати допоміжний тип Omit
, наданий TypeScript, або
створити власний.
type MyOmit<F, S> = { [P in keyof F as P extends S ? never : P]: F[P] };
type EverythingFromTExceptK<T, K> = MyOmit<T, K>;
Тепер давайте виберемо всі властивості з K
, присутні в T
, і позначимо їх як
необов’язкові. Ми можемо зробити це за допомогою
типів зіставлення.
type OptionalProperties<T, K> = {
[P in keyof T as P extends K ? P : never]?: T[P];
};
Дивовижно, правда? Тепер, коли у нас є обидві частини нашого рішення, давайте об’єднаємо їх.
type PartialByKeys<T, K = keyof T> = OptionalProperties<T, K> &
EverythingFromTExceptK<T, K>;
Зверніть увагу, що це все ще не вирішує нашу проблему. Придивившись ближче до
згенерованого типу, ми побачимо, що PartialByKeys
повертає
{...properties} & {...some other properties}
. Отже, щоб отримати остаточну
відповідь, нам потрібно об’єднати ці два типи в один.
type MyMerge<T> = { [P in keyof T]: T[P] };
type PartialByKeys<T, K = keyof T> = MyMerge<
OptionalProperties<T, K> & EverythingFromTExceptK<T, K>
>;
Коментарі