Утилитарные типы: Partial, Pick, Omit, Record
Готовые инструменты, которые конструируют новые типы из уже существующих.
Утилитарные типы — встроенные дженерики TypeScript, которые преобразуют один тип в другой: делают свойства необязательными, выбирают часть полей и т. д.
Зачем они нужны
Часто нужен тип, «похожий» на существующий, но с отличиями: те же поля, но все необязательные; только часть полей; всё без одного поля. Переписывать тип вручную — дублирование, которое легко рассинхронизировать. Утилитарные типы строят такие варианты автоматически из исходного типа.
Все примеры строятся на базовом интерфейсе:
interface User {
id: number;
name: string;
email: string;
age: number;
}
Partial — все поля необязательны
Partial<T> делает все свойства опциональными. Идеально для функций обновления, где меняют только часть полей:
function updateUser(id: number, changes: Partial<User>) {
// changes может содержать любое подмножество полей User
}
updateUser(1, { age: 31 }); // ок — только возраст
updateUser(1, { name: "Боря", age: 40 }); // ок — несколько полей
Без Partial пришлось бы передавать целиком весь объект User или вручную писать тип со всеми ?.
Required — все поля обязательны
Обратная операция: Required<T> делает все свойства обязательными, убирая ?. Полезно, когда нужно гарантировать заполненность всех полей.
Pick — выбрать часть полей
Pick<T, Keys> создаёт тип из перечисленных свойств. Удобно для «облегчённых» представлений:
type UserPreview = Pick<User, "id" | "name">;
// эквивалентно { id: number; name: string }
const preview: UserPreview = { id: 1, name: "Аня" }; // email и age не нужны
Omit — всё, кроме указанного
Omit<T, Keys> — наоборот, берёт все поля, кроме перечисленных. Классика — тип для создания записи без id (его выдаёт база):
type NewUser = Omit<User, "id">;
// { name: string; email: string; age: number }
function createUser(data: NewUser) { /* ... id присвоит база */ }
Record — типизированный словарь
Record<Keys, Value> создаёт тип объекта с заданными ключами и типом значений — компактная альтернатива индексной сигнатуре:
type Roles = Record<string, boolean>;
// эквивалентно { [key: string]: boolean }
const access: Record<"read" | "write", boolean> = {
read: true,
write: false,
}; // ключи ограничены литералами — пропустить один нельзя
Памятка
| Утилита | Что делает |
Partial<T> | все свойства необязательны |
Required<T> | все свойства обязательны |
Pick<T, K> | только выбранные поля |
Omit<T, K> | все поля, кроме указанных |
Record<K, V> | объект с ключами K и значениями V |
Главная польза — единый источник правды. Меняете базовый User — все производные типы (Partial<User>, Omit<User, "id">) обновляются сами, без ручной правки.
Итог
Partial/Requiredпереключают обязательность всех свойств.PickиOmitвыбирают или исключают поля исходного типа.Record<K, V>описывает словарь; все утилиты автоматически следуют за изменениями базового типа.