Menu

Служебные типы TypeScript: полный список с примерами

Все встроенные служебные типы TypeScript в одном месте: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ReturnType, Awaited, строковые типы и другие, у каждого описание в одну строку и запускаемый пример.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Служебные типы это встроенные в TypeScript обобщённые типы, которые превращают один тип в другой. Вместо второго типа User со всеми необязательными полями вы пишете Partial<User>; вместо копирования трёх полей Pick<User, "id" | "name">. Они глобальные, поэтому импорт не нужен.

Когда меняется User, все четыре производных типа следуют за ним. Стандартная библиотека TypeScript (lib.es5.d.ts) объявляет 22 служебных типа. Ниже перечислены все они, сгруппированные по виду типов, с которыми работают, со ссылкой на подробную страницу там, где она есть.

Объектные типы: Partial, Required, Readonly, Pick, Omit, Record

Служебный типЧто делаетПример
Partial<T>делает каждое свойство необязательнымPartial<User> для данных обновления
Required<T>делает каждое свойство обязательным (убирает ?)Required<Config> после применения значений по умолчанию
Readonly<T>делает каждое свойство readonlyReadonly<State>
Pick<T, K>оставляет только ключи KPick<User, "id" | "name">
Omit<T, K>убирает ключи KOmit<User, "password">
Record<K, V>объектный тип с ключами K и значениями VRecord<"en" | "de", string>

Required<T> противоположен Partial<T>; страница о Partial описывает оба, включая явное undefined, которое пропускает такое развёртывание.

Типы объединения: Exclude, Extract, NonNullable

Служебный типЧто делаетПример
Exclude<U, M>убирает члены объединения, присваиваемые в MExclude<"a" | "b" | "c", "a"> это "b" | "c"
Extract<U, M>оставляет члены объединения, присваиваемые в MExtract<string | number, number> это number
NonNullable<T>убирает null и undefinedNonNullable<string | null> это string

Эти три работают с объединениями, а не с объектами. В этом ключевое отличие от Pick и Omit, которые принимают объектный тип и список его ключей.

Типы функций и классов: Parameters, ReturnType и другие

Служебный типЧто делаетПример
ReturnType<F>тип возврата типа функцииReturnType<typeof createStore>
Parameters<F>типы параметров в виде кортежаParameters<typeof fetchPage>[0]
ConstructorParameters<C>параметры конструктора класса в виде кортежаConstructorParameters<typeof Point>
InstanceType<C>тип экземпляра, который создаёт конструкторInstanceType<typeof Point>
ThisParameterType<F>тип параметра this функцииThisParameterType<typeof greet>
OmitThisParameter<F>тип функции без параметра thisтип greet.bind(obj)
ThisType<T>задаёт тип this внутри методов объектного литералаиспользуется с noImplicitThis в API-билдерах
NoInfer<T>запрещает выводить параметр типа из этой позицииfallback: NoInfer<C>

typeof createOrder нужен потому, что эти утилиты принимают тип, а createOrder это значение. С классами то же самое: typeof Point это тип конструктора, а просто Point как тип уже означает тип экземпляра.

NoInfer управляет тем, откуда дженерик берёт свой тип:

Без NoInfer TypeScript вывел бы C из обоих аргументов и расширил бы его до "red" | "green" | "blue", так что опечатка в запасном значении была бы принята.

Строковые типы: Uppercase, Lowercase, Capitalize, Uncapitalize

Служебный типЧто делаетПример
Uppercase<S>переводит строковый литеральный тип в верхний регистрUppercase<"get"> это "GET"
Lowercase<S>переводит его в нижний регистрLowercase<"GET"> это "get"
Capitalize<S>делает первый символ заглавнымCapitalize<"name"> это "Name"
Uncapitalize<S>делает первый символ строчнымUncapitalize<"Name"> это "name"

Эти четыре встроены в компилятор, а не написаны на TypeScript, и полезнее всего внутри шаблонных литеральных типов, например `on${Capitalize<E>}` для имён обработчиков событий.

Промисы: Awaited

Служебный типЧто делаетПример
Awaited<T>тип, который получается из await, с разворачиванием вложенных промисовAwaited<Promise<Promise<number>>> это number

Awaited<ReturnType<typeof fn>> это стандартный способ назвать тип результата асинхронной функции, не объявляя его отдельно.

Сочетание служебных типов

Служебные типы вкладываются друг в друга. Несколько сочетаний встречаются так часто, что их стоит знать наизусть:

Читайте вложенный служебный тип изнутри наружу: Readonly<Pick<Post, "id" | "title">> сначала оставляет два свойства, а затем делает их доступными только для чтения. Из тех же частей строится помощник PartialBy, который делает необязательными только некоторые ключи; он выписан на странице о Partial.

Служебные типы ничего не делают во время выполнения

Каждый служебный тип стирается при компиляции кода. Значение с типом Omit<User, "password"> во время выполнения всё равно может нести пароль, если он был в исходном объекте:

Тип только ограничивает то, что вашему коду разрешено читать. Чтобы удалить поле из данных, уберите его деструктуризацией, как в последних строках, а чтобы запретить изменения во время выполнения, используйте Object.freeze, а не Readonly. Встроенные типы это однострочные сопоставленные и условные типы, так что теми же средствами можно написать и свои.

Часто задаваемые вопросы

Что такое служебные типы в TypeScript?

Обобщённые типы, которые поставляются с TypeScript и преобразуют другие типы: Partial<T> делает каждое свойство необязательным, Pick<T, K> оставляет часть свойств, ReturnType<F> получает тип возврата функции и так далее. Они объявлены в стандартной библиотеке, поэтому используются без импорта.

Нужно ли импортировать служебные типы?

Нет. Partial, Omit, Record, ReturnType и остальные это глобальные типы из встроенных файлов библиотеки TypeScript. Пишите Partial<User> где угодно; не нужны ни импорт, ни пакет npm.

Какие служебные типы встроены в TypeScript?

22, все объявлены в lib.es5.d.ts: Partial, Required, Readonly, Pick, Omit, Record, Exclude, Extract, NonNullable, Parameters, ConstructorParameters, ReturnType, InstanceType, ThisParameterType, OmitThisParameter, ThisType, NoInfer, Awaited, Uppercase, Lowercase, Capitalize и Uncapitalize.

Меняют ли служебные типы объекты во время выполнения?

Нет. Они только описывают типы и стираются из вывода JavaScript. Omit<User, "password"> не удаляет свойство password, а Readonly<T> ничего не замораживает. Чтобы изменить сам объект, напишите код: деструктуризацию с rest, Object.freeze и так далее.

Можно ли написать собственные служебные типы?

Да. Встроенные это обычный TypeScript: большинство из них это однострочные сопоставленные или условные типы в lib.es5.d.ts. type Nullable<T> = { [K in keyof T]: T[K] | null } это собственный служебный тип, написанный тем же способом.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ