Enum и альтернативы
Enum — способ задать набор именованных значений. В TypeScript есть, но у него есть нюансы.
Числовой enum
Idle,
Loading,
Success,
Error,
}
let status: Status = Status.Idle;
По умолчанию Idle = 0, Loading = 1 и так далее.
С заданными значениями
Idle = 1,
Loading = 2,
Success = 3,
}
Строковый enum
Idle = 'idle',
Loading = 'loading',
Success = 'success',
}
let status: Status = Status.Idle;
Строковые enum безопаснее: значение читаемо в логах.
Константный enum
const enum Status {
Idle = 'idle',
Loading = 'loading',
}
Компилятор вставляет значения напрямую, без создания объекта. Быстрее, но есть ограничения.
Проблемы enum
Runtime-код
Обычный enum создаёт объект в рантайме. Это увеличивает бандл.
Несовместимость с erasableSyntaxOnly
Современный тренд — писать TypeScript, который компилируется в JS без дополнительного кода. enum этому противоречит.
Не работает с union
enum Status { Idle, Loading }
function handle(s: Status) {}
handle('idle'); // ошибка
Альтернатива: union литералов
type Status = 'idle' | 'loading' | 'success' | 'error';
let status: Status = 'idle';
Плюсы:
- Нет runtime-кода
- Совместимо с JSON
- Работает везде
- Проще
Альтернатива: объект as const
Если нужны и тип, и значения:
const Status = {
Idle: 'idle',
Loading: 'loading',
Success: 'success',
} as const;
type Status = typeof Status[keyof typeof Status];
// 'idle' | 'loading' | 'success'
let status: Status = Status.Idle;
Плюсы:
- Есть объект для итерации
- Есть тип
- Нет runtime-накладок
Когда enum оправдан
- Проект старый, уже использует enum
- Нужны reverse-mapping (числовой enum)
- Команда привыкла к enum
Во всех новых проектах — union или as const.
Пример: замена enum
// Было
enum Role {
Admin = 'admin',
User = 'user',
}
function check(role: Role) {}
// Стало
type Role = 'admin' | 'user';
function check(role: Role) {}
Или:
const Role = {
Admin: 'admin',
User: 'user',
} as const;
type Role = typeof Role[keyof typeof Role];
Object.values(Role); // ['admin', 'user']
Итоги
- Enum создаёт runtime-код
- Строковые enum читаемы, числовые — компактны
- Union литералов — современная альтернатива
as const+typeof— если нужен объект- В новых проектах enum не нужен