type alias: объявление
typealias в 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 alias —
type 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.
Связанные темы
- interface -- объявление и использование
- interface vs type -- когда что
- Branded Types
- Union Types
- Mapped types
- _MOC TypeScript