type alias: объявление

type alias в TypeScript — именованный синоним для любого типа: примитива, объекта, union, intersection, кортежа, функции или вычисленного через утилиты типа. В отличие от interface, type alias может представлять любую форму типа, не только объект.

Зачем нужно

Type alias позволяет дать имя сложному типу, чтобы переиспользовать его и улучшить читаемость кода. Это единственный способ именовать union, intersection, tuple и conditional типы.

Где используется

  • Именование union типов: type Status = "active" | "inactive"
  • Псевдонимы примитивов для документации: type UserId = string
  • Функциональные типы: type Handler = (e: Event) => void
  • Кортежи: type Pair = [string, number]
  • Сложные mapped и conditional типы

Основной контент

Базовый синтаксис

// Псевдоним примитива
type UserId   = string;
type Quantity = number;

// Объектный тип
type Point = {
  x: number;
  y: number;
};

// Использование
const userId: UserId = "u-123";
const p: Point = { x: 0, y: 0 };

Union type alias

type Status    = "pending" | "active" | "inactive";
type Id        = string | number;
type Nullable<T> = T | null;
type Maybe<T>    = T | null | undefined;

function setStatus(s: Status): void { /* ... */ }
setStatus("active");  // OK
setStatus("unknown"); // Error

Функциональные типы

type Predicate<T>    = (value: T) => boolean;
type Transform<A, B> = (input: A) => B;
type Callback        = (err: Error | null, data?: string) => void;
type EventHandler    = (e: MouseEvent) => void;

const isPositive: Predicate<number> = (n) => n > 0;
const toString: Transform<number, string> = (n) => String(n);

Кортежи

type Pair        = [string, number];
type RGB         = [red: number, green: number, blue: number];
type Coordinates = [lat: number, lng: number];

const coord: Coordinates = [55.75, 37.62];
const [lat, lng] = coord; // lat: number, lng: number

Generic type alias

type Result<T, E = Error> =
  | { ok: true; data: T }
  | { ok: false; error: E };

type ApiResponse<T> = {
  data: T;
  meta: { total: number; page: number };
};

type Nullable<T> = T | null;
type Optional<T> = T | undefined;
type Maybe<T>    = T | null | undefined;

Рекурсивный type alias

type JsonPrimitive = string | number | boolean | null;
type JsonObject    = { [key: string]: JsonValue };
type JsonArray     = JsonValue;
type JsonValue     = JsonPrimitive | JsonObject | JsonArray;

Сравнение с interface

// Эквивалентны для объектов:
interface UserI { name: string }
type     UserT = { name: string };

// Только type:
type Union = "a" | "b";           // interface не может
type Mapped = { [K in "a" | "b"]: number }; // mapped type
type Conditional<T> = T extends string ? "yes" : "no";

// Только interface:
interface Extended extends UserI { age: number }  // declaration merging

Частые ошибки

  • Два одинаковых type aliastype User = ... дважды — ошибка; в отличие от interface, type не поддерживает merging.
  • Использовать type для declaration merging — невозможно; если нужен merging — используйте interface.
  • Ожидать что type alias создаёт новый тип — TypeScript использует структурную совместимость; type UserId = string и string взаимозаменяемы. Для номинальной типизации нужны Branded Types.
  • Глубокая рекурсия — рекурсивные type alias могут вызвать Type instantiation is excessively deep.

Связанные темы

Ресурсы