Готовые утилитарные типы в TypeScript основаны на мощной возможности языка создавать новые типы на основе существующих с помощью перебора ключей и трансформации значений.
Этот механизм называется Mapped Types.
Mapped Types решают проблему повторения структуры объектов при создании вариаций типов, например, когда нужно сделать все поля обязательными, опциональными или readonly.
Мы можем создать свой Partial или Readonly.
type MyPartial<T> = {
[K in keyof T]?: T[K];
};
type MyReadonly<T> = {
readonly [K in keyof T]: T[K];
};
type User = { name: string; age: number; };
type PartialUser = MyPartial<User>;
type ReadonlyUser = MyReadonly<PartialUser>;
const partialUser: PartialUser = {};
const readonlyUser: ReadonlyUser = {};Внутри типа используется запись K in keyof T, которая означает, что мы итерируемся по ключам переданного объекта. В K попадает сам ключ, а дальше мы возвращаем его значение.
Существуют следующие модификаторы:
— ? для опциональности: [K in keyof T]?: T[K]
— readonly, чтобы сделать значение только для чтения: readonly [K in T]: T[K]
С помощью знака минус можно сделать обратное действие, например, убрать readonly или сделать обязательными поля, как это реализовано, например, в типе Required.
// Make all properties in T required
type Required<T> = {
[P in keyof T]-?: T[P];
};
🟣Можно использовать тип never для исключения значений, как это сделано в типах Exclude и Extract:
// Exclude from T those types that are assignable to U
type Exclude<T, U> = T extends U ? never : T;
// Extract from T those types that are assignable to U
type Extract<T, U> = T extends U ? T : never;
🟣В TypeScript 4.1 и выше можно менять имена свойств в mapped types с помощью конструкции as
type MappedTypeWithNewProperties<Type> = {
[Properties in keyof Type as NewKeyType]: Type[Properties];
};Часть as NewKeyType говорит: «возьми старое имя свойства и преврати его в новое имя».
🟣В реальности этим не так часто приходится пользоваться в разработке.
Но на собесах по TypeScript достаточно часто просят написать свою реализацию определенного утилитарного типа.
✈️ Telegram | 🎓 Менторство | 📹YouTube | 👩💻 Roadmap