PickByType
Проблема
Из входного параметра T
выберите те свойства, которые присваиваемые к U
.
Например:
type OnlyBoolean = PickByType<
{
name: string;
count: number;
isReadonly: boolean;
isEnable: boolean;
},
boolean
>; // { isReadonly: boolean; isEnable: boolean; }
Решение
В этой проблеме нам нужно перебрать все ключи объекта. В момент перебора, нам
необходимо отфильтровать и оставить только те ключи, которые присваиваемые к
U
. Очевидно, что начать нам нужно с сопоставляющих типов.
Так что давайте начнём с того, что сделаем просто копию входящего объекта:
type PickByType<T, U> = { [P in keyof T]: T[P] };
Сначала, мы получили все ключи из T
и применили к ним итерацию. На каждой
итерации, TypeScript возьмет ключ и присвоит его к параметру P
. Имея этот
ключ, мы можем получить нужный нам тип с использованием конструкции T[P]
.
Теперь, применяя фильтр к этой итерации, мы сможем оставить только нужные нам ключи. Когда я говорю “фильтр”, я подразумеваю переопределение ключа в этой ситуации. Мы можем переопределить ключ на каждой итерации и оставить только интересующие нас:
type PickByType<T, U> = {
[P in keyof T as T[P] extends U ? never : never]: T[P];
};
Обратите внимание на ключевое слово as
. Это оператор, который заменит наш тип
P
на тип указанный с помощью as
. И нас ничего не останавливает от того,
чтобы написать условный тип после as
. С помощью этого условного типа мы и
проверим наше условие.
В случае, если тип значения из объекта присваиваемый к типу, который указан в
U
- оставляем ключ без изменений. Но, если тип оказывается не присваиваемый,
то в таком случае мы должны его игнорировать - возвращаем never
:
type PickByType<T, U> = { [P in keyof T as T[P] extends U ? P : never]: T[P] };
Таким образом, мы реализовали тип, который может фильтровать ключи объектов по их типам.
Комментарии