Дата публикации:

Эта заметка появилась под впечатлением от статьи «Why I don't use enums in TypeScript, and neither should you», которая сейчас удалена. Её автор предлагал вместо enum использовать в TypeScript объекты.

То есть вместо:

enum Colors {
  BLUE = 'blue',
  GREEN = 'green',
  RED = 'red',
}
function printColor(color: Colors) { console.log(color); }
printColor(Colors.BLUE);
printColor('blue');

предлагалось писать:

const Colors = {
  BLUE: 'blue',
  GREEN: 'green',
  RED: 'red',
} as const;
type Colors = typeof Colors[keyof typeof Colors];
function printColor(color: Colors) { console.log(color); }
printColor(Colors.BLUE);
printColor('blue');

Преимуществом называли возможность писать литерал 'blue', не импортируя модуль с перечислением.

В статье «Какова конечная цель программирования?» я рассматриваю иерархию целей разработки, похожую на пирамиду Маслоу.

Подход со строковыми литералами относится к первому уровню — удобству написания кода. Но он не достигает высшего уровня, который я называю изменяемостью.

Действительно, литерал писать проще:

invoice.setState('pending');
order.setState('pending');

Но при поиске всех состояний pending для заказов они смешаются с такими же состояниями счетов. Именно от этого защищают кажущиеся неудобствами импорт и отказ от литералов.

В моём JS-коде я использую пространства имён, унаследованные от Zend1:

const TeqFw_Core_Shared_Enum_Sphere = {
  BACK: 'BACK',
  FRONT: 'FRONT',
  SHARED: 'SHARED',
};
Object.freeze(TeqFw_Core_Shared_Enum_Sphere);
export default TeqFw_Core_Shared_Enum_Sphere;

При использовании подключаю перечисление через внедрение зависимостей и JSDoc:

export default function ({ TeqFw_Core_Shared_Enum_Sphere$: SPHERE }) {
  if (one.sphere === SPHERE.FRONT || one.sphere === SPHERE.SHARED) {
    // ...
  }
}

Так обычным текстовым поиском находятся все места использования TeqFw_Core_Shared_Enum_Sphere. JSDoc помогает IDE перейти к каждому значению — BACK, FRONT или SHARED.

JavaScript, в отличие от TypeScript, не запрещает передать литерал напрямую. Но ответственность разработчика — использовать возможности инструментов во благо, а не во вред. Да, enum в JavaScript фактически не реализован, хотя слово зарезервировано. Но я считаю полезным писать код так, как будто он есть.