Гид по технологиям

TypeScript: основные utility‑типы и примеры

5 min read TypeScript Обновлено 05 Jan 2026
TypeScript: основные utility‑типы и примеры
TypeScript: основные utility‑типы и примеры

TypeScript расширяет JavaScript статической типизацией и содержит встроенные utility-типы, упрощающие работу с типами. В этой статье собраны основные utility-типы (Partial, Pick, Readonly, Required, Omit, Record), их примеры, когда их использовать, альтернативы и практические чек-листы.

Ноутбук MacBook Pro с экраном, на котором видно фрагмент кода программы

Введение

TypeScript — надмножество JavaScript, которое добавляет статическую типизацию. Utility-типы в TypeScript — это готовые обобщённые типы, которые помогают трансформировать существующие интерфейсы и типы без повторения кода. Они повышают читаемость, уменьшают количество ошибок и ускоряют рефакторинг.

Важно: в одной статье приведены практические подсказки, типичные ошибки и альтернативы. Определение терминов: utility‑тип — предопределённый тип в TypeScript, который принимает другие типы и возвращает новый тип.

Partial — сделать свойства необязательными

Описание

Partial превращает все свойства типа T в необязательные (optional). Это полезно для частичных обновлений, форм и шагов конфигурации.

Пример:

interface User {
  name: string;
  age: number;
  email: string;
}

type OptionalUser = Partial;

const user: OptionalUser = { name: "John" };

Когда использовать

  • Формы с частичным заполнением.
  • Функции, принимающие патчи (patch) для объекта.

Ограничения и подводные камни

  • Partial делает свойства необязательными, но не меняет их типы — если свойство было сложным (вложенным объектом), его вложенные поля остаются прежними. Для глубокого Partial нужен рекурсивный тип.

Альтернативы

  • Создать собственный тип с нужными optional-полями вручную.
  • Использовать Pick для точного выбора свойств.

Пример глубокой версии (упрощённо):

type DeepPartial = {
  [P in keyof T]?: T[P] extends object ? DeepPartial : T[P];
};

Pick — выбрать подмножество свойств

Описание

Pick создаёт новый тип, содержащий только перечисленные свойства K исходного типа T.

Пример:

interface User {
  location: string;
  age: number;
  email: string;
}

type PersonWithoutEmail = Pick;

const person: PersonWithoutEmail = {
  location: 'USA',
  age: 30
};

Когда использовать

  • Ограничение возвращаемого API-фрагмента.
  • Интерфейсы данных для отображения в UI, когда нужны только определённые поля.

Когда Pick не подходит

  • Если нужно исключить несколько полей, удобнее Omit.
  • Если требуется переименовать ключи — придётся использовать дополнительные маппинги.

Альтернатива: Omit для исключения свойств (см. ниже).

Readonly — сделать свойства неизменяемыми

Описание

Readonly делает все свойства типа T доступными только для чтения. Это защита от случайных изменений после создания объекта.

Пример:

interface User {
  name: string;
  age: number;
  email: string;
}

type ReadonlyUser = Readonly;

const user: ReadonlyUser = {
  name: "John",
  age: 30,
  email: "john@example.com"
};

// user.name = "Jane"; // Ошибка: нельзя присвоить, свойство только для чтения

Когда использовать

  • Константные конфигурации.
  • Объекты, которые передаются между модулями и не должны изменяться.

Ограничения

  • Readonly делает свойства поверхностно неизменяемыми; для глубокой неизменности нужен рекурсивный тип DeepReadonly.

Required — все свойства обязательны

Описание

Required делает все свойства типа T обязательными. Это противоположность Partial.

Пример с корректными типами:

interface User {
  name: string;
  location: string;
  address: string;
}

type RequiredUser = Required;

const user: RequiredUser = {
  name: "John Doe",
  location: "USA",
  address: "Kansas 9745-0622"
};

Когда использовать

  • Валидировать, что после некоторой стадии все поля заполнены.
  • Приведение частичных данных к полному типу перед сохранением.

Когда Required не поможет

  • Если нужны условно обязательные поля (зависимость между полями). Для этого нужны условные типы и валидация на уровне логики.

Omit — исключить свойства из типа

Описание

Omit создаёт новый тип на основе T за вычетом свойств K. Это удобный способ убрать лишние поля.

Пример (исправлено — корректный синтаксис):

interface Person {
  location: string;
  age: number;
  email: string;
}

type PersonWithoutEmail = Omit;

const person: PersonWithoutEmail = { location: "USA", age: 30 };

Когда использовать

  • Исключение внутренних полей (паролей, токенов) из публичного типа.
  • Создание DTO без определённого набора полей.

Совпадение с Pick

Omit часто используется как противоположность Pick: Omit эквивалентен Pick>.

Record — задать типы для ключей и значений

Описание

Record создаёт тип объекта с ключами K и значениями типа T. K обычно — указанное множество ключей или базовый тип ключей (string | number | symbol).

Определение:

type Record = { [P in K]: T };

Пример:

type MyRecord = Record;

const myObject: MyRecord = {
  "foo": 1,
  "bar": 2,
  "baz": 3,
};

Когда использовать

  • Маппинг по ключам со строгой типизацией (например, перевод строк, метрики, конфигурации для окружений).
  • Когда набор ключей известен заранее — используйте union литералов вместо string для безопасных ключей.

Пример с union ключей:

type Sizes = 'small' | 'medium' | 'large';
type SizeMap = Record;

const sizeMap: SizeMap = { small: 1, medium: 2, large: 3 };

Практическая методология выбора utility-типа

Краткий план при выборе типа:

  1. Определите, какие свойства вам нужны: все, часть или исключение — Pick/Partial/Omit.
  2. Нужна ли неизменяемость — Readonly.
  3. Нужен ли строго определённый набор ключей — Record с union-ключами.
  4. Нужны ли глубокие преобразования — реализуйте рекурсивные версии (DeepPartial, DeepReadonly).

Мини‑методология (шаблон):

  • Для DTO на входе: Partial или Pick.
  • Перед сохранением в БД: Required + валидация.
  • Для конфигураций: Readonly или Record.
  • Для API-ответов: Omit для удаления внутренних полей.

Чек-листы по ролям

Разработчик (frontend)

  • Использовать Pick для пропсов компонента с минимально необходимыми полями.
  • Для форм использовать Partial или DeepPartial для удобства.
  • Не мутировать props — применяйте Readonly, где нужно.

Code reviewer

  • Проверить, не раскрываются ли внутренние поля в типах ответа (использовать Omit).
  • Убедиться, что Record использует union-ключи, а не plain string, если ключи известны.

Backend/Integration

  • Привести внешние данные к Required типам после валидации.
  • Для кэша и метрик применять Record с описанными ключами.

Чит‑шит (краткая шпаргалка)

  • Partial — все поля optional.
  • Required — все поля обязательны.
  • Readonly — все поля readonly.
  • Pick — выбрать набор полей K.
  • Omit — исключить набор полей K.
  • Record — объект с ключами K и значениями T.

Когда utility-типы «не сработают» (примеры ошибок)

  • Когда бизнес-правило требует зависимости между полями (например, если A задано, то B обязателен). Utility-типы не моделируют такие зависимости — нужна дополнительная логика или условные типы.
  • Глубокие структуры: Partial делает только поверхностные поля optional; для вложенных объектов нужен DeepPartial.
  • При переименовании полей: Pick/Omit не переименовывают поля — требуется маппинг.

Ментальные модели и эвристики

  • Utility-типы — это трансформеры типа: они берут входной тип и возвращают новый. Представьте их как функции над описаниями структуры данных.
  • Всегда думайте про глубину трансформации: shallow vs deep.
  • Отдавайте предпочтение сочетанию типов вместо копирования интерфейсов по всему коду — это облегчает рефакторинг.

Решение выбора (flowchart)

flowchart TD
  A[Нужна трансформация типа?] -->|да| B{Поменять все свойства?}
  B -->|все optional| C[Partial]
  B -->|все readonly| D[Readonly]
  B -->|все required| E[Required]
  B -->|нет| F{Выбрать или исключить поля}
  F -->|выбрать| G[Pick]
  F -->|исключить| H[Omit]
  A -->|нет| I[Оставить исходный тип]
  A -->|создать мапу ключ→значение| J[Record]

Краткое резюме

Utility-типы ускоряют разработку и улучшают поддержку типов. Часто используются в связке: Pick + Partial, Omit + Required и т. п. Помните про глубину преобразований и про то, что для сложных зависимостей нужны условные или рекурсивные типы.

Важно

  • Не придумывайте в типах бизнес-валидацию — типы помогают на ранней стадии, но runtime‑валидация остаётся обязательной.

Ключевые выводы

  • Используйте Partial для патчей и форм.
  • Используйте Pick/Omit для ограничения видимости полей.
  • Используйте Readonly для защиты конфигураций.
  • Record удобен для маппинга по фиксированным ключам.

1-строчная глоссарий

  • Utility‑тип — предопределённый обобщённый тип в TypeScript, который трансформирует другие типы.

Если нужно, могу подготовить готовые snippets для ESLint/TSConfig или примеры DeepPartial/DeepReadonly для вашего кода.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство