Enum de TypeScript: numérico, string, const y alternativas | We.Inc
Genera enums numéricos, de string y const a partir de tus propios nombres de miembros, mira el JavaScript exacto que emite cada uno y compáralos con objetos as const y uniones de literales.
Un enum da un único tipo a un conjunto de constantes con nombre. Los enums numéricos cuentan desde 0 y además asignan los números de vuelta a los nombres; los enums de string necesitan un literal por miembro y no tienen reverse mapping; los const enums se insertan en línea y desaparecen. A diferencia de casi todo TypeScript, los enums normales emiten JavaScript real, por eso muchos equipos prefieren objetos as const.
Cinco formas de modelar un conjunto fijo de valores
Estilo
¿Emite JavaScript?
Reverse mapping
¿Acepta un literal directo?
Enum numérico
Sí, un objeto
Sí, de número a nombre
Números que coinciden con un miembro
Enum de string
Sí, un objeto
No
No, hay que usar Enum.Member
const enum
No, valores en línea
No
Según su tipo de enum
Objeto as const
Sí, un objeto normal
No (escribe uno si lo necesitas)
Sí
Unión de literales
No, se elimina
No
Sí
Escribe nombres de miembros en el generador y cambia entre estilos. Escribe la declaración en TypeScript y el JavaScript que generaría el compilador, para que veas el coste de cada opción antes de que llegue a tu bundle.
Escribe los nombres de los miembros separados por comas, por ejemplo Draft, Review, Live.
Para enums numéricos, fija el número inicial; los miembros siguientes cuentan a partir de él.
Elige un estilo para ver su declaración, el JavaScript que emite y cómo se usa.
Copia la versión que encaje con tu proyecto.
Elige enums de string u objetos as const para valores que salen de tu programa, como campos de API o columnas de base de datos. Una línea de log que dice live se lee mejor que 2.
Nunca reordenes ni insertes miembros en medio de un enum numérico que se guarda en algún sitio. Todos los números posteriores cambian y los datos guardados pasan a significar otra cosa.
Evita const enum en librerías publicadas. Quien las use compilando con isolatedModules o con un type stripper no puede insertar en línea valores de otro archivo.
Activa erasableSyntaxOnly si ejecutas archivos .ts con el type stripping de Node; marca los enums antes de que fallen en tiempo de ejecución.
Preguntas frecuentes
¿Qué es un reverse mapping?
En los enums numéricos, tsc guarda ambas direcciones en el objeto, así que Direction.Up es 0 y Direction[0] es el string Up. Los miembros de string no tienen entrada inversa, porque el valor podría coincidir con el nombre de otro miembro.
¿Por qué no puedo pasar un string normal a una función que recibe un enum de string?
Los miembros de un enum de string son tipos distintos. El compilador indica que el literal no es asignable al enum, así que quien la use debe escribir Status.Draft. Si quieres que se pueda pasar el literal, usa en su lugar una unión de literales de string.
¿Cómo recorro los valores de un enum?
En un enum de string, Object.values(MyEnum) devuelve los valores. En un enum numérico el objeto también contiene las claves inversas, así que filtra: Object.values(MyEnum).filter((v) => typeof v === 'number').
¿Están obsoletos los enums?
No. Siguen formando parte de TypeScript. La opción más reciente erasableSyntaxOnly, añadida en TypeScript 5.8, simplemente permite prohibirlos a los proyectos que dependen del type stripping, porque un enum no se puede quitar borrando anotaciones.
¿Node.js ejecuta directamente archivos con enums?
No con el type stripping por defecto. La documentación de Node incluye las declaraciones enum entre las funciones que necesitan generar código y no están soportadas en ese modo, así que compílalas con tsc u otro transformador, o cambia a un objeto as const.
Enums numéricos: compactos pero frágiles
Sin inicializadores, los miembros se numeran 0, 1, 2 en orden. Dale un valor al primero, como Low = 1, y los demás siguen a partir de ahí. El objeto emitido contiene tanto de nombre a número como de número a nombre.
Esa compacidad también es el riesgo. Los números no significan nada fuera de tu código, y añadir un miembro en medio vuelve a numerar en silencio todo lo que viene después.
Enums de string: legibles y estrictos
Cada miembro necesita un literal de string, lo que hace que los valores se expliquen solos en logs, URLs y JSON. La rigidez corta en ambos sentidos: un valor leído de una API es un string, no el enum, así que sigues necesitando una comprobación antes de tratarlo como tal.
El patrón as const
Un objeto literal marcado con as const conserva sus valores de string exactos como tipos. Combínalo con type Role = (typeof Role)[keyof typeof Role] y obtienes un objeto en tiempo de ejecución para iterar más un tipo unión que acepta tanto Role.Admin como el literal admin.
Es JavaScript normal con anotaciones, así que cualquier type stripper lo maneja, y no se genera nada aparte del objeto que escribiste.
Los tres tipos de enum y lo que emiten
Enum numérico con valor inicial
Mid y High siguen contando desde Low. El objeto resultante asigna en ambas direcciones.
Enum de string
Cada miembro se asigna una vez, sin entrada inversa.
const enum
La declaración desaparece y cada uso se convierte en su valor.
Alternativas que se pueden eliminar
Objeto as const más una unión derivada
Funciona con type strippers, se recorre con Object.values y acepta el string directo.
Unión simple cuando no hace falta una lista en tiempo de ejecución
Se elimina por completo; el compilador sigue rechazando cualquier otro string.
Prohibir enums en un proyecto con type stripping
Con esta opción, una declaración enum es un error de compilación.
Enum numérico
Enum de string
const enum
Objeto as const
Tipo unión
Generador de enums
Nombre del tipo
Miembros (separados por comas)
Primer número
Estilo de enum
TypeScript
JavaScript emitido
Copiar TypeScript
Copiar JavaScript
Usa nombres que empiecen por una letra, $ o _, que solo contengan letras, dígitos, $ o _, y sin repetir ningún nombre.