Por qué siempre uso enum en JavaScript

Fecha de publicación: 2024-05-23

Escribí esta nota bajo la influencia de un artículo ya eliminado que proponía usar objetos en lugar de enum en TypeScript.

En vez de:

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

se sugería usar:

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');

La ventaja sería poder escribir 'blue' sin importar el módulo que define la enumeración.

En mi artículo sobre la meta última de programar describo una jerarquía de objetivos parecida a la pirámide de Maslow.

Usar literales favorece el primer nivel, la comodidad al escribir. Pero no alcanza el nivel más alto: la capacidad de modificar el sistema con seguridad.

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

Es cómodo, pero al buscar todos los estados pending de pedidos se mezclarán con los de facturas. La importación y el uso de símbolos evitan justamente esa ambigüedad.

En mi código JavaScript uso espacios de nombres inspirados en 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;

Al usarlo, incorporo la enumeración mediante inyección de dependencias y JSDoc:

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

Así una búsqueda de texto encuentra todos los usos de TeqFw_Core_Shared_Enum_Sphere, y JSDoc ayuda al IDE a localizar cada valor. JavaScript no prohíbe usar literales directamente; es responsabilidad del programador usar las herramientas con criterio. Aunque enum no esté implementado realmente en JavaScript, considero útil escribir como si lo estuviera.

Fragmentos adicionales de código fuente

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 where TeqFw_Core_Shared_Enum_Sphere is 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 (
) {
}