El enum es de lo poco de TypeScript que no desaparece al compilar: genera código. Por eso Node 24, que ejecuta los .ts borrando los tipos, no lo acepta. Vemos qué produce, un agujero de los enum numéricos y las dos alternativas que se usan hoy.
También te puede interesar
Un enum y lo que genera
enum Color {
Rojo,
Verde,
Azul,
}
enum Estado {
Activo = "activo",
Pausado = "pausado",
}
console.log(Color.Verde, Color[1], Estado.Pausado);Al compilarlo a JavaScript, los tipos desaparecen, pero los enum no. Se convierten en objetos construidos con una función:
"use strict";
var Color;
(function (Color) {
Color[Color["Rojo"] = 0] = "Rojo";
Color[Color["Verde"] = 1] = "Verde";
Color[Color["Azul"] = 2] = "Azul";
})(Color || (Color = {}));
var Estado;
(function (Estado) {
Estado["Activo"] = "activo";
Estado["Pausado"] = "pausado";
})(Estado || (Estado = {}));
console.log(Color.Verde, Color[1], Estado.Pausado);El enum numérico crea el objeto en los dos sentidos: Color.Verde es 1 y Color[1] es "Verde".
Node 24 no lo ejecuta
Node 24 ejecuta TypeScript quitando las anotaciones de tipo, sin traducir nada. Un enum no se puede quitar sin más, así que falla:
node con-enum.ts
salidanode:internal/modules/run_main:107
triggerUncaughtException(
^
file:///w/enum/con-enum.ts:1
> enum Color {
Rojo,
Verde,
Azul,
> }
SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode
code: 'ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX'
}
Node.js v24.22.0Se puede activar la traducción con una opción experimental, que avisa de que puede cambiar:
node --experimental-transform-types con-enum.ts
salida(node:45) ExperimentalWarning: Transform Types is an experimental feature and might change at any time (Use `node --trace-warnings ...` to show where the warning was created) 1 Verde pausado
Y la opción erasableSyntaxOnly de TypeScript avisa antes de ejecutar, en todos los enum del proyecto:
npx tsc --noEmit --strict --target esnext --module nodenext --types node --locale es --erasableSyntaxOnly con-enum.ts
tsccon-enum.ts(1,6): error TS1294: Esta sintaxis no se permite cuando "erasableSyntaxOnly" está habilitado. con-enum.ts(7,6): error TS1294: Esta sintaxis no se permite cuando "erasableSyntaxOnly" está habilitado.
El agujero de los enum numéricos
Desde TypeScript 5.0, pasar el literal 42 donde se espera un Color es un error. Pero un number cualquiera sigue entrando:
enum Color {
Rojo,
Verde,
Azul,
}
function pintar(c: Color): string {
return `color número ${c}`;
}
console.log(pintar(Color.Azul));
const leidoDeUnFormulario: number = 42;
console.log(pintar(leidoDeUnFormulario)); // ¿42? No hay ningún color 42, y TypeScript lo aceptanpx tsc --strict --target esnext --module esnext --locale es numerico.ts node numerico.js
salidacolor número 2 color número 42
Compila sin errores y pinta un «color número 42» que no existe. Un número leído de un formulario o de una API pasa sin comprobación.
Alternativa 1: un objeto as const
Un objeto normal con as const conserva los valores exactos. De él se saca una unión con typeof y keyof. Se usa igual que un enum, pero es JavaScript puro:
// La alternativa: un objeto normal «congelado» con as const, y una unión sacada de él.
const Estado = {
Activo: "activo",
Pausado: "pausado",
Cancelado: "cancelado",
} as const;
type Estado = (typeof Estado)[keyof typeof Estado]; // "activo" | "pausado" | "cancelado"
function etiqueta(e: Estado): string {
switch (e) {
case Estado.Activo:
return "En curso";
case Estado.Pausado:
return "En pausa";
case Estado.Cancelado:
return "Cancelada";
}
}
console.log(etiqueta(Estado.Pausado));
console.log(etiqueta("cancelado")); // también vale el texto tal cual
console.log(Object.values(Estado)); // se puede recorrer: es un objeto de verdadÁbrelo en el editor y cámbialo →
npx tsc --noEmit --strict --target esnext --module nodenext --types node --locale es constante.ts
node constante.ts
salidaEn pausa Cancelada [ 'activo', 'pausado', 'cancelado' ]
Y no acepta valores que no están:
const Estado = { Activo: "activo", Pausado: "pausado" } as const;
type Estado = (typeof Estado)[keyof typeof Estado];
function etiqueta(e: Estado): string {
return e;
}
etiqueta("borrado");tscconstante-error.ts(6,10): error TS2345: No se puede asignar un argumento de tipo ""borrado"" al parámetro de tipo "Estado".
Alternativa 2: una unión de literales
Si no necesitas recorrer los valores ni darles nombre, una unión de textos basta:
// Si no hace falta recorrer los valores, basta con una unión de literales.
type Talla = "chica" | "mediana" | "grande";
const precios: Record<Talla, number> = { chica: 45, mediana: 55, grande: 65 };
function cobrar(t: Talla, cantidad: number): string {
return `$${(precios[t] * cantidad).toFixed(2)} MXN`;
}
console.log(cobrar("mediana", 3));Ábrelo en el editor y cámbialo →
npx tsc --noEmit --strict --target esnext --module nodenext --types node --locale es union.ts
node union.ts
salida$165.00 MXN
enum | Objeto as const | Unión de literales | |
|---|---|---|---|
| Genera código | Sí | El objeto, que es JavaScript normal | No |
| Node 24 lo ejecuta tal cual | No | Sí | Sí |
| Se pueden recorrer los valores | Sí | Sí, con Object.values | No |
Acepta un number cualquiera | Sí, si es numérico | No | No |
| Acepta el texto directamente | No: hay que escribir Estado.Activo | Sí | Sí |
Todo el código de esta página se comprobó con TypeScript 7.0.2 en modo estricto (--strict --locale es) y se ejecutó con Node.js 24.22 en un contenedor limpio antes de publicarla; los mensajes de error y las salidas están copiados de esa ejecución. Documentación oficial: Objects vs Enums en el manual de TypeScript.