Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працюють utility types на кшталт Partial, Pick, Omit, Record і що таке mapped types?

Utility types - вбудовані перетворення типів, щоб не описувати схожі форми вручну:

interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

type UserUpdate = Partial<Omit<User, 'id'>>;   // усі поля, крім id, необов'язкові
type PublicUser = Omit<User, 'password'>;
type UserPreview = Pick<User, 'id' | 'name'>;
type RolesMap = Record<'admin' | 'editor', string[]>;
type Frozen = Readonly<User>;

Ще корисні: Required, NonNullable, ReturnType<typeof fn>, Parameters<typeof fn>, Awaited<Promise<T>>.

Під капотом це mapped types - тип, що проходить по ключах іншого типу:

type MyPartial<T> = {
  [K in keyof T]?: T[K];
};

// Модифікатори можна і додавати, і знімати
type Mutable<T> = {
  -readonly [K in keyof T]: T[K];
};

// Перейменування ключів через as (TS 4.1+)
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type UserGetters = Getters<Pick<User, 'name'>>;   // { getName: () => string }

Навіщо на практиці: один джерельний тип (User), а похідні - форма оновлення, публічне представлення, стан форми - виводяться з нього. Додали поле в User - усі похідні оновилися, і компілятор покаже місця, які треба доробити.

Обережно: надто «розумні» типи важко читати й налагоджувати, а повідомлення про помилки в них стають незрозумілими. Якщо тип потрібно пояснювати, інколи простіше описати його явно.

Докладніше в документації: Utility Types

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання