ПрограммированиеFullstack разработчик

Как работает типизация enum в TypeScript, какие есть виды enum, и в чём различие между константными и вычисляемыми значениями? Какие подводные камни могут возникнуть при использовании enum?

Проходите собеседования с ИИ помощником Hintsage

Ответ

В TypeScript поддерживаются два вида enum:

  • Числовые (numeric) — значения по умолчанию присваиваются по порядку, начиная с 0.
  • Строковые (string) — каждое значение должно быть задано явно, и оно является строкой.

Также бывают гетерогенные enum'ы (смешанные типы), но их использование крайне не рекомендуется.

Пример:

enum Status { Init, Loading, Ready = 5, Error } // Status.Error === 6 enum HttpCode { Ok = 200, NotFound = 404, Internal = 'INTERNAL_ERROR' // Error! Только строки или только числа } enum Direction { Up = 'UP', Down = 'DOWN', }

Константные значения вычисляются на этапе компиляции. Если значение ENUM зависит от других вычислений или выражений (например, функция), это становится вычисляемым значением (computed member). Только предыдущие члены enum могут быть использованы для подсчёта текущего члена как значения по умолчанию.

Важные особенности:

  • Числовые enum'ы поддерживают обратное отображение enum → число → строка-имя.
  • Строковые enum'ы — только прямое (имя → значение).
  • Ошибки компиляции при смешивании типов в одном enum.

Вопрос с подвохом

Можно ли использовать значение другого enum'а при объявлении члена нового enum?

Ответ: Да, но только если это значение — константа или раньше объявленный член.

Пример:

enum A { X = 1 } enum B { Y = A.X } // ОК

Однако нельзя использовать вычисления на основе функций или данных из других мест (например, вызовы функций).

Примеры реальных ошибок из-за незнания тонкостей темы.


История

В проекте для сериализации данных во внешний API был использован числовой enum. При смене порядка членов enum значения "поплыли", и внешние системы начали получать другие числа. Это вызвало неверные состояния на внешних клиентах, которых было невозможно отследить без аудита кода.


История

В одном React-проекте ошибочно использовали строковой и числовой enum в switch-case, ожидая, что значения приводимы к строкам. Из-за несоответствия switch не срабатывал корректно, и компонент возвращал невалидный UI.


История

При попытке сделать enum, где часть значений вычисляется через функцию, TypeScript не ругался, но в ряде сборок значения оказывались undefined. Это привело к проблемам с роутингом, когда enum использовался как идентификатор для путей. Критическая ошибка воспроизводилась только в production bundle.