Перечисления (Enums) в TypeScript

Перечисления позволяют нам определять набор именованных числовых констант и определяются при помощи ключевого слова enum. Перечисления являются подтипами примитивного типа number.

Тело перечисления состоит из нуля или более членов, каждый из которых имеет ассоциированное с ним значение, которое может быть либо постоянным, либо вычисляемым. Постоянным значение будет в случае:

  • если значение не определено явно и значение предыдущего члена является постоянным. В этом случае значение будет равно числовому значению предыдущего члена плюс 1. Исключение составляет только первый элемент. Если значение не указано, то оно становится равным 0;
  • если элемент перечисления определяется с помощью константного выражения. Такие выражения представляют собой разновидность выражений TypeScript, которые могут быть вычислены на этапе компиляции.

Выражение перечисления является константным, если:

  • это вычисляемый литерал;
  • это ссылка на определенное ранее константное значение члена перечисления (может быть даже в другом перечислении). Если элемент определен в том же перечислении, то на него можно ссылаться по имени;
  • это константное выражение перечисления, заключенное в скобки;
  • содержит унарные операторы +, -, ~;
  • содержит бинарные операторы +, -, *, /, %, <<, >>, >>>, &, |, ^. Если результатом выражения будет NaN или Infinity, то будет ошибка компиляции.

Во всех остальных случаях член перечисления считается вычисляемым и его значение вычисляется во время выполнения программы.

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

После компиляции мы получим следующий код:

В сгенерированном коде перечисление превращается в объект, который хранит как прямые (name — value), так и обратные (value-name) связи между значением и именем элемента. Члены объекта перечисления по сути являются его свойствами.

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

Константные перечисления

Для того, чтобы не генерировать дополнительный код и лишние ссылки для доступа к значениям перечислений, можно использовать константные перечисления. Они определяются с помощью ключевого слова const, которое ставится перед enum. Использование константных перечислений увеличивает производительность кода, поскольку вместо элемента перечисления используется ассоциированная с ним константа.

Такие перечисления должны иметь только константные выражения и в процессе компиляции ссылки на свойства объекта-перечисления заменяются значениями:

Если сделать данное перечисление обычным, то есть убрать const, то получим:

Рассмотрим еще пример:

Теперь посмотрим, как будет выглядеть функция someFunc после компиляции:

Как видно, вместо элементов перечисления были подставлены соответствующие константы.

“Окружающие” перечисления

Такие перечисления определяются с помощью ключевого слова declare. Они используются для описания формы уже существующих перечислений.

Отличием таких перечислений является то, что если элемент у такого перечисления не имеет инициализатора, то он считается вычисляемым. В обычных перечислениях — наоборот.

Компилятор не будет генерировать код для таких перечислений. Это может быть полезным при использовании сторонних библиотек (например jQuery, в которой определен какой-то объект (напр. $) когда вам нужна информация об объекте, но не нужно генерировать код.

Like what you read? Give Sergey Bakaev a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.