Почему я всегда использую enum в JavaScript
Дата публикации: 2024-05-23Эта заметка появилась под впечатлением от статьи «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 фактически не реализован, хотя слово зарезервировано. Но я считаю полезным писать код так, как будто он есть.
Дополнительные фрагменты исходного кода
const TeqFw _Core_Shared_Enum_Sphere = {
}; Object.freeze(TeqFw _Core_Shared_Enum_Sphere); export default TeqFw _Core_Shared_Enum_Sphere;
export default function (
{
}
) {
if (
) {
} } With this approach, you can find all the places whereTeqFw_Core_Shared_Enum_Sphereis used through simple text search. Using JSDoc annotations helps the IDE (PhpStorm) navigate through the code and find usages of each individual value (BACK,FRONT,SHARED) within the IDE.
if (
) {
}