Menu

Псевдонимы типов в TypeScript: ключевое слово type

Псевдоним типа даёт имя любому типу через ключевое слово type: структурам объектов, объединениям, кортежам, функциям, обобщённым и рекурсивным типам. Синтаксис, как выглядит каждая форма и почему псевдоним это лишь имя, а не новый отдельный тип.

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

Псевдоним типа даёт имя типу. Вы пишете type Name = ..., и с этого момента Name можно использовать везде, где ожидается тип. В отличие от интерфейса, псевдоним может назвать вообще любой тип, а не только структуры объектов.

Псевдонимы существуют только при компиляции. В сгенерированном JavaScript нет ни одной из этих строк type.

Синтаксис

type Name = SomeType;
type Name<T> = SomeTypeUsing<T>;       // generic
export type Name = SomeType;           // exported from a module

Имена по соглашению пишутся в PascalCase. Правая часть это любое выражение типа, и псевдоним может использовать другие псевдонимы, включая самого себя (см. рекурсивные типы ниже). Псевдоним доступен во всей области видимости, где он объявлен, даже выше строки объявления, потому что типы проверяются при компиляции, а не выполняются по порядку, как const или let.

Объектные типы

Для структуры объекта псевдоним и интерфейс записываются почти одинаково. Псевдоним использует = и обычно завершается точкой с запятой.

Псевдоним не может использовать extends; эту роль играет пересечение &. Проверка лишних свойств, необязательные и readonly свойства работают точно так же, как у интерфейсов. Что из двух выбрать для структур объектов, разобрано на странице interface или type.

Объединения, кортежи и функции

Это случаи, которые может назвать только псевдоним, и главная причина существования type. Псевдоним объединения перечисляет варианты, псевдоним кортежа фиксирует длину и типы элементов массива, а псевдоним функции описывает сигнатуру.

В scale параметрам не нужны аннотации: их типы задаёт псевдоним Transform. Синтаксис кортежей описан в разделе кортежи, а сужение объединений на странице о типах объединения.

Обобщённые псевдонимы типов

Параметры типа позволяют одному псевдониму работать со многими типами. У них могут быть значения по умолчанию, как у параметров функций.

Result<number> использует значение по умолчанию E = string. Небольшие обобщённые псевдонимы вроде type Nullable<T> = T | null или type Dict<T> = Record<string, T> часто встречаются в реальном коде. Встроенные служебные типы (Partial<T>, Pick<T, K>, ReturnType<F>) тоже обобщённые псевдонимы, объявленные в стандартной библиотеке.

Псевдонимы это имена, а не новые типы

Псевдоним не создаёт отдельный тип. Это второе имя для типа справа, и компилятор считает их идентичными. Два псевдонима для string полностью взаимозаменяемы:

Этот код печатает cancelling u_42 без ошибки, и это как раз та ошибка, которую псевдоним не может предотвратить. Псевдоним всё равно помогает читателю (параметр с типом OrderId говорит больше, чем string), но если перепутать два идентификатора должно быть ошибкой компиляции, используйте брендированный тип, например string & { readonly __brand: "OrderId" }.

Рекурсивные псевдонимы типов

Псевдоним может ссылаться на себя; так описывают деревья, вложенные списки и JSON:

Псевдоним Json отвергает значения, которые JSON не может представить: { when: new Date() } или { f: undefined }, присвоенные в Json, это ошибки компиляции (TS2322).

Типы из значений: typeof

Если значение уже существует, можно назвать его тип, а не выписывать его. Оператор типа typeof читает тип переменной и сочетается с другими операторами:

const defaults = { retries: 3, verbose: false, level: "info" };

type Options = typeof defaults;
// { retries: number; verbose: boolean; level: string }

type OptionKey = keyof typeof defaults;
// "retries" | "verbose" | "level"

function start(port: number) {
  return { port, startedAt: new Date() };
}
type Server = ReturnType<typeof start>;
// { port: number; startedAt: Date }

Значение остаётся единственным источником истины: добавьте свойство в defaults, и Options последует за ним. Подробнее в разделе typeof.

Экспорт и импорт псевдонимов

Псевдонимы экспортируются и импортируются как значения. import type явно показывает, что импортируется только тип, поэтому такой импорт всегда удаляется из вывода JavaScript:

// shapes.ts
export type Point = { x: number; y: number };
export type Shape = { kind: "circle"; center: Point; radius: number };

// main.ts
import type { Point, Shape } from "./shapes.js";

const p: Point = { x: 1, y: 2 };

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

Что такое псевдоним типа в TypeScript?

Псевдоним типа это имя для типа, объявленное ключевым словом type: type Point = { x: number; y: number }. После этого Point можно использовать везде, где ожидается тип. Он может назвать любой тип: структуру объекта, объединение, кортеж, сигнатуру функции, примитив или обобщённый тип.

Создаёт ли псевдоним типа новый тип?

Нет. Псевдоним это лишь другое имя существующего типа. С type UserId = string и type OrderId = string значение UserId можно передать туда, где ожидается OrderId, потому что оба это просто string. Чтобы получить невзаимозаменяемые типы, используйте брендированный тип.

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

Да, если ссылка на себя вложена в объектный тип, массив или кортеж: type TreeNode = { value: number; children: TreeNode[] } и псевдоним Json, включающий Json[], оба работают. Прямая ссылка вроде type Loop = Loop | string это ошибка TS2456, Type alias 'Loop' circularly references itself.

Может ли псевдоним типа быть обобщённым?

Да. Укажите параметры типа после имени: type Box<T> = { value: T }, а затем используйте его как Box<number>. У параметров могут быть значения по умолчанию (type Result<T, E = string> = ...) и ограничения (type Keys<T extends object> = keyof T).

Как получить тип из существующего объекта?

Используйте оператор типа typeof: const defaults = { retries: 3, verbose: false }; type Options = typeof defaults; даёт { retries: number; verbose: boolean }. Так остаётся один источник истины, когда значение появляется первым.

Coddy programming languages illustration

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

НАЧАТЬ