Cómo obtener nombres de enum en TypeScript: magia bajo el capó

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: La pregunta eterna en Stack Overflow

\n\n

¿Alguna vez te has preguntado cómo los desarrolladores experimentados en TypeScript obtienen los nombres de los valores enum? Si has mirado en Stack Overflow, seguramente has visto la pregunta con miles de visitas: "How to get names of enum entries?". Parecería sencillo, ¿verdad? Pero en la práctica, muchos principiantes (y no solo) tropiezan en este punto.

\n\n

En este artículo no solo daremos una respuesta lista. Nos meteremos bajo el capó de TypeScript y analizaremos cómo funcionan exactamente los enum, cómo el compilador los transforma en JavaScript y por qué algunos enfoques para obtener nombres pueden provocar errores inesperados. ¿Listos? ¡Allá vamos!

\n\n

¿Qué es un enum en TypeScript y para qué sirven sus nombres?

\n\n

Un enum (enumeración) es una forma conveniente de definir un conjunto de constantes con nombre. En TypeScript, pueden ser numéricos (por defecto) y de cadena. Pero, ¿qué hacer si necesitas obtener el nombre de un valor específico? Por ejemplo, recibes de una API el código de estado 403 y quieres mostrar al usuario un mensaje claro como "Forbidden".

\n\n
enum HttpStatus {\n  OK = 200,\n  NotFound = 404,\n  Forbidden = 403\n}\n\n// Nuestra tarea: obtener el nombre "Forbidden" a partir del valor 403\n
\n\n

Parece que TypeScript debería proporcionar un método incorporado para esto. Pero no. Hay que escribir nuestra propia lógica. Y aquí empieza lo interesante.

\n\n

Solución directa: Object.keys y Object.values

\n\n

La forma más obvia es usar los métodos Object.keys() o Object.values(). Muchos principiantes escriben algo como esto:

\n\n
function getEnumName(enumObj: any, value: number): string | undefined {\n  const keys = Object.keys(enumObj);\n  return keys.find(key => enumObj[key] === value);\n}\n\nconsole.log(getEnumName(HttpStatus, 403)); // "Forbidden" — ¡funciona!\n
\n\n

Parece lógico, ¿verdad? Sí. Pero si pruebas este código con un enum numérico, te llevas una sorpresa. Veamos en qué se compila nuestro HttpStatus.

\n\n

Bajo el capó: compilación de un enum numérico

\n\n

Cuando TypeScript compila un enum numérico, crea un objeto con mapeo inverso (reverse mapping). Así es como se ve el JavaScript compilado:

\n\n
var HttpStatus;\n(function (HttpStatus) {\n    HttpStatus[HttpStatus["OK"] = 200] = "OK";\n    HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";\n    HttpStatus[HttpStatus["Forbidden"] = 403] = "Forbidden";\n})(HttpStatus || (HttpStatus = {}));\n\n// El objeto HttpStatus resultante se ve así:\n// { \n//   "200": "OK", \n//   "404": "NotFound", \n//   "403": "Forbidden", \n//   "OK": 200, \n//   "NotFound": 404, \n//   "Forbidden": 403 \n// }\n
\n\n

¿Ves el truco? El compilador añade tanto claves numéricas como claves de cadena. Por lo tanto, Object.keys(HttpStatus) devolverá no solo ["OK", "NotFound", "Forbidden"], sino también ["200", "404", "403"]. ¡Esto rompe la lógica de nuestra solución simple!

\n\n

Para evitarlo, hay que filtrar las claves numéricas:

\n\n
function getEnumNameSafe(enumObj: any, value: number): string | undefined {\n  const keys = Object.keys(enumObj).filter(key => isNaN(Number(key)));\n  return keys.find(key => enumObj[key] === value);\n}\n
\n\n

Pero este código parece un parche. ¿Hay una forma mejor?

\n\n

Enums de cadena: otra historia

\n\n

Si usas enums de cadena, no se crea el mapeo inverso. Esto simplifica la tarea:

\n\n
enum Direction {\n  Up = "UP",\n  Down = "DOWN",\n  Left = "LEFT",\n  Right = "RIGHT"\n}\n\n// Object.keys(Direction) devolverá solo ["Up", "Down", "Left", "Right"] — ¡ideal!\n
\n\n

Pero, ¿qué pasa si necesitas obtener el nombre a partir del valor? El mismo Object.keys funciona perfectamente:

\n\n
function getStringEn                

Blogs

Book Recommendations