Привет Всем.
Меня зовут Михаил. В НЛМК нахожусь на должности Frontend-разработчика. Занимаюсь разработкой внутренних информационных систем на React + Typescript.
В этой статье поговорим про тип enum (перечисление) в Typescript, о случаях когда его можно и нужно использовать, а когда нет.
Перечисления бывают числовыми и строковыми. Например, представим в виде перечисления должности работников кафе.
Рассмотрим перечисления с числовыми значениями:

Каждому элементу перечисления соответствует числовая константа начиная с 0 и увеличивается на 1 при движении сверху вниз по перечислению.
В этом легко убедиться:

в консоле мы увидим следующее:

Можно менять порядок, если проинициализировать один из элементов числовым значением.

Тогда элементы после будут увеличены на 1 от заданного значения:

Рассмотрим перечисления со строковыми значениями:

в консоли мы увидим:

Числовые и строковые перечисления можно смешивать.
TypeScript компилируется в JavaScript. При компиляции типы удаляются и остается чистый JavaScript код. Например, простая функция суммирования с определением типов

превратится в:

Как мы видим, компилятор удалил все объявления типов.
Но с enum это работает немного иначе.
Разберем для чего и когда можно использовать enum, а когда лучше обойтись простым константным объектом.
Основной аргумент против enum - при компиляции enum, компилятор создает дополнительный JavaScript код и усложняет работу компилятору.
Вернемся к примеру с перечислением должностей работников кафе.
Используем enum и посмотрим на результат компиляции:

превратилось в:

Получили не очень приятную конструкцию, состоящую из переменной и анонимного самовызывающегося функционального выражения.
При этом можно использовать методы объекта, например:

В консоли мы увидим:

Попробуем заменить enum на константный объект и посмотрим результаты компиляции:

превратится в:

Тут константный объект определенно хорош.
Но enum может еще лучше!
Для этого используем ключевое слово const:

Взглянем на результат компиляции:

Теперь нет объекта, нет лишней переменной и анонимного самовызывающегося функционального выражения.
Получается, enum использовать даже профитнее, чем объект?
В этой части да, но есть несколько нюансов:
Если в вашем проекте в файле tsconfig.json в секции compilerOptions свойство preserveConstEnums выставлено со значением true, то эффекта от использования const enum не будет.
Проверим это на нашем примере.
Поставим флаг в true:

И посмотрим на результат компиляции:

превратился в:

Т.е. весь эффект от использования const enum потерян и не имеет смысла.
Если вам необходим только доступ к значению, то однозначно используйте enum.
А вот если вам нужно где-то перебрать или получить все значения или ключи, то используйте константный объект а не const enum.
Почему не const enum, смотрим:

Мы увидим ошибку:

А все потому, что нашего const enum не окажется в скомпилированном коде.
Когда необходимо получить все значения или ключи, константный объект в скомпилированном коде сильно выигрывает у enum без использования const.
О типизации
Типизируем параметр принимаемый функцией “printPosition”:

или так:

Но руками создавать union тип - это не то, что хотелось бы делать.
При использовании enum:
если нам где-то понадобится типизировать принимаемый параметр по ключам enum.

если нам где-то понадобится типизировать принимаемый параметр по значениям enum:

достаточно использовать шаблонную строку. Главное не забывать использовать const.
Итак, подытожим плюсы и минусы использования enum:
Минусы:
При использовании enum без const компилятор создает дополнительный JavaScript код, что усложняет работу компилятору и размер финального бандла;
При использовании enum с const - нет возможности получить для обработки все ключи или значения enum.
Необходимо следить за флагом свойства preserveConstEnums в файле tsconfig.json в секции compilerOptions, чтобы получить профит.
Плюсы:
При использовании const enum и необходимости только в значении дает отсутствие избыточного кода в скомпилированном JavaScript, а значит, меньший размер и лучшую производительность;
При использовании const enum - возможность быстрой и удобной типизации в отличие от использования константных объектов;
Использование enum упрощает рефакторинг кода, изменение значения enum автоматически обновляет все его использования в проекте. Это помогает избежать ошибок, связанных с поиском и заменой значений вручную.
Обнаружение ошибок на этапе компиляции: TypeScript выдаст ошибку на этапе компиляции, если использовать значение, которое не входит в enum. Это помогает избежать ошибок при использовании неверных значений.
Автодополнение в редакторах кода: Редакторы кода предлагают автодополнение для значений enum, что ускоряет процесс написания кода, уменьшает вероятность опечаток и ошибок.
Самодокументируемый код: Определение enum с именованными значениями добавляет дополнительную информацию о том, какие значения ожидаются и задумывались разработчиком. Это делает код более самодокументируемым и легче понимаемым для других разработчиков.
Итого:
На мой взгляд, понимание плюсов и минусов использования enum при разработке несомненно даст исключительно положительный эффект, как минимум, это уменьшение размера бандла и легкая типизация.
Спасибо за внимание! Пишите комментарии, буду рад узнать ваше мнение по данному вопросу!