Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между Enum и Union в TypeScript
Enum и Union Type - это два разных способа определить набор допустимых значений, но они работают по-разному и решают разные проблемы.
Enum - структура данных с именованными константами
Enum создает объект с именованными значениями:
enum Status {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
Pending = 'PENDING'
}
// Использование:
const userStatus: Status = Status.Active; // 'ACTIVE'
const otherStatus: Status = Status.Pending; // 'PENDING'
// Enum тоже создает объект в runtime:
console.log(Status.Active); // 'ACTIVE'
console.log(Status['ACTIVE']); // 'Active'
console.log(Object.keys(Status)); // ['Active', 'Inactive', 'Pending']
Компилируется в JavaScript:
var Status;
(function (Status) {
Status["Active"] = "ACTIVE";
Status["Inactive"] = "INACTIVE";
Status["Pending"] = "PENDING";
})(Status || (Status = {}));
Union Type - тип, объединяющий несколько типов
Union определяет что переменная может быть одним из нескольких значений:
type Status = 'ACTIVE' | 'INACTIVE' | 'PENDING';
// Использование:
const userStatus: Status = 'ACTIVE'; // OK
const otherStatus: Status = 'PENDING'; // OK
const badStatus: Status = 'UNKNOWN'; // ERROR: Type '"UNKNOWN"' is not assignable to type 'Status'
Компилируется в пустоту (type erasure):
// Union Types полностью удаляются при компиляции в JavaScript
// Остается только значение
const userStatus = 'ACTIVE';
const otherStatus = 'PENDING';
Ключевые отличия
1. Runtime vs Compile-time
// ENUM - существует в runtime
enum Color {
Red = 'RED',
Green = 'GREEN'
}
function convertColor(c: Color): string {
switch(c) {
case Color.Red: return 'red';
case Color.Green: return 'green';
}
}
// Union Type - стирается в runtime
type Color = 'RED' | 'GREEN';
function convertColor(c: Color): string {
switch(c) {
case 'RED': return 'red';
case 'GREEN': return 'green';
}
}
2. Размер бундла
// Enum добавляет код в бандл
enum Status { Active, Inactive }
// Результат: ~200 байт JavaScript
// Union Type не добавляет ничего
type Status = 'ACTIVE' | 'INACTIVE';
// Результат: 0 байт (стирается)
3. Обратное отображение (Enum)
enum Color {
Red = 'RED',
Green = 'GREEN'
}
// Можешь получить ключ по значению
const key = Color['RED']; // 'Red'
// С Union это невозможно без дополнительного кода
type Color = 'RED' | 'GREEN';
// Нет встроенного способа получить 'RED' -> 'Red'
4. Проверка типа
// Enum - можешь проверить в runtime
enum Status { Active = 'ACTIVE', Inactive = 'INACTIVE' }
function isValidStatus(value: any): value is Status {
return Object.values(Status).includes(value);
}
isValidStatus('ACTIVE'); // true
isValidStatus('UNKNOWN'); // false
// Union - нужен более сложный type guard
type Status = 'ACTIVE' | 'INACTIVE';
function isValidStatus(value: any): value is Status {
return value === 'ACTIVE' || value === 'INACTIVE';
}
// Или const assertion
const validStatuses = ['ACTIVE', 'INACTIVE'] as const;
type Status = typeof validStatuses[number];
Когда использовать что
Используй Union Type когда:
// 1. Просто типизация, нет нужды в runtime объекте
type UserRole = 'admin' | 'user' | 'guest';
// 2. Хочешь минимизировать бундл
// Union добавляет 0 байт
// 3. Данные приходят с API в виде строк
interface User {
id: string;
role: 'admin' | 'user' | 'guest'; // Приходит так с API
}
// 4. Хочешь простоту
type Status = 'pending' | 'success' | 'error';
const [status, setStatus] = useState<Status>('pending');
Используй Enum когда:
// 1. Нужны константы в runtime
enum HttpStatus {
OK = 200,
Created = 201,
BadRequest = 400,
Unauthorized = 401,
NotFound = 404
}
function handleResponse(status: HttpStatus) {
if (status === HttpStatus.OK) { ... }
}
// 2. Нужно обратное отображение
enum Color { Red = 'RED', Green = 'GREEN' }
const name = Color['RED']; // Только для Enum
// 3. Нужна итерация по всем значениям
enum Role { Admin, User, Guest }
const roles = Object.values(Role);
// 4. Нужна валидация в runtime
function isValidRole(role: any): boolean {
return Object.values(Role).includes(role);
}
Практические примеры
Пример 1: Статусы формы
// Union - лучший выбор
type FormStatus = 'idle' | 'loading' | 'success' | 'error';
const [status, setStatus] = useState<FormStatus>('idle');
if (status === 'loading') {
return <Spinner />;
}
Пример 2: HTTP методы
// Union - простой и понятный
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
const request = (url: string, method: HttpMethod) => {
// ...
};
Пример 3: Ролевой контроль доступа
// Enum - хорош для сложной логики
enum Permission {
Read = 1,
Write = 2,
Delete = 4
}
const userPermissions = Permission.Read | Permission.Write;
const canDelete = (userPermissions & Permission.Delete) !== 0;
Пример 4: Данные с сервера
// Union Type - берешь как приходит
interface ApiResponse {
status: 'success' | 'error';
message: string;
}
// vs Enum - преобразуешь
enum Status { Success = 'success', Error = 'error' }
const api = async (): Promise<Status> => {
const response = await fetch('...');
const data = await response.json();
return data.status as Status;
};
Правило большого пальца
Union Type:
✓ Используй по умолчанию
✓ Меньше кода
✓ Меньше бундла
✓ Понятнее для большинства случаев
Enum:
✓ Используй если нужен объект в runtime
✓ Нужна проверка по Object.values()
✓ Нужны битовые операции или маски
✓ Сложная логика с константами
Лучшая практика: Union Type + Const Object
// Лучший подход - типизация + runtime константы
const STATUS = {
ACTIVE: 'ACTIVE',
INACTIVE: 'INACTIVE',
PENDING: 'PENDING'
} as const;
type Status = typeof STATUS[keyof typeof STATUS];
// Получаешь:
// - Типизацию (Status type)
// - Runtime значения (STATUS объект)
// - Минимальный бундл
// - Безопасность от опечаток
const userStatus: Status = STATUS.ACTIVE; // Типобезопасно
const allStatuses = Object.values(STATUS); // Итерация возможна
Заключение
Enum и Union Type решают разные проблемы:
- Union Type - для типизации, меньше boilerplate, рекомендуется по умолчанию
- Enum - когда нужен runtime объект и сложная логика
В современном TypeScript часто лучше использовать Union Type + const объект вместо Enum для баланса между типобезопасностью и производительностью.