Перечисления (enum)

Именованный набор связанных констант вместо «магических» чисел и строк.

enum — перечисление: набор именованных констант, объединённых под одним типом.

Проблема магических значений

Код часто пестрит «магическими» числами и строками, смысл которых неясен:

function setStatus(status: number) { /* ... */ }
setStatus(2); // что значит 2? непонятно

Что такое 2 — «выполнено», «отменено», «в работе»? Приходится держать значения в голове или лезть в документацию. enum заменяет такие значения понятными именами.

Числовой enum

По умолчанию enum нумерует элементы с нуля автоматически:

enum Status {
  Todo,       // 0
  InProgress, // 1
  Done,       // 2
}

function setStatus(status: Status) { /* ... */ }

setStatus(Status.InProgress); // понятно, что происходит
setStatus(5);                 // Ошибка: 5 не входит в enum Status

Теперь вместо загадочной 2 пишут Status.Done — читаемо и защищено: передать значение вне набора нельзя.

Строковый enum

Числа в логах и базе данных нечитаемы. Строковый enum хранит осмысленные значения — это удобнее при отладке и сериализации:

enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

console.log(Direction.Up); // "UP" — видно, что это, а не 0

Строковые enum чаще предпочтительны: их значения самодокументируемы и не «плывут» при добавлении новых элементов в середину.

Проверяемый пример

const Direction = { Up: "UP", Down: "DOWN" };

function describe(dir) {
  return "Движемся: " + dir;
}

console.log(describe(Direction.Up));
console.log(describe(Direction.Down));

Вывод:

Движемся: UP
Движемся: DOWN

enum или union литералов?

Похожего результата можно добиться union-типом из литералов: type Status = "todo" | "done". Разница:

enumunion литералов
создаёт объект в рантаймеисчезает после компиляции
есть Status.Done как значениетолько строки "done"
чуть больше кода в JS«нулевая стоимость»

Многие команды сегодня предпочитают union литералов — он легче и не оставляет следа в рантайме. enum берут, когда нужен именно объект-перечисление, доступный во время выполнения.

Итог

  • enum даёт имена набору связанных констант — конец «магическим» числам и строкам.
  • Числовой enum нумерует с нуля; строковый хранит читаемые значения (предпочтительнее для логов и БД).
  • Альтернатива — union литералов: легче и без следа в рантайме; выбор зависит от задачи.
Проверьте себя
1. Какую проблему в первую очередь решает enum?
AУскоряет выполнение программы
BЗаменяет непонятные «магические» числа и строки осмысленными именами
CУменьшает размер кода
DПозволяет хранить функции
2. Какое значение по умолчанию у первого элемента числового enum?
A1
B0
C-1
Dимя элемента в виде строки
3. Чем строковый enum удобнее числового на практике?
AОн работает быстрее
BЕго значения читаемы в логах и базе и не «плывут» при вставке новых элементов
CОн занимает меньше памяти
DОн не требует объявления
Поддержать проект