Что такое enum в TypeScript
Что проверяют
Знаете ли вы отличие от остальных конструкций языка и понимаете ли, почему его часто советуют не использовать.
Как отвечать
Перечисление это именованный набор констант. Бывает числовым, где значения проставляются автоматически с нуля, и строковым, где значение задаётся явно.
Ключевое отличие от почти всего остального в TypeScript: перечисление существует во время выполнения. Компилятор генерирует для него настоящий объект, тогда как типы стираются полностью. Отсюда следуют и достоинства, и претензии.
Что не так:
- числовой вариант небезопасен: исторически в переменную такого типа можно было присвоить произвольное число, никак с ним не связанное. В новых версиях это ужесточили, но осадок остался;
- обратное отображение у числового варианта: сгенерированный объект содержит и имена по значениям, и значения по именам. Перебор такого объекта даёт неожиданный результат;
- лишний код в сборке: объект попадает в итоговый файл, хотя нужен был только тип;
- вариант с подстановкой значений решает предыдущую проблему, но плохо совместим с раздельной компиляцией файлов, которая используется современными сборщиками.
Что советуют вместо него:
const Status = { Active: "active", Closed: "closed" } as const;
type Status = (typeof Status)[keyof typeof Status];Такой объект даёт и значения для использования в коде, и тип, ограничивающий допустимые строки. Либо, когда объект во время выполнения не нужен, достаточно объединения строковых литералов.
Когда перечисление всё же уместно: когда набор значений нужен именно как объект во время выполнения, например для перебора всех вариантов, и когда так принято в существующем коде проекта. Единообразие важнее теоретической чистоты.
Где спотыкаются
Используют числовой вариант там, где нужны строковые значения.
Перебирают числовое перечисление и получают удвоенные ключи.
Берут вариант с подстановкой и ломают сборку.
Не знают про объединение строковых литералов как более лёгкую замену.