Comment obtenir les noms d'enum en TypeScript : la magie sous le capot

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : La question éternelle sur Stack Overflow

\n\n

Vous êtes-vous déjà demandé comment les développeurs expérimentés en TypeScript obtiennent les noms des valeurs enum ? Si vous avez jeté un œil sur Stack Overflow, vous avez sûrement vu la question avec des milliers de vues : "How to get names of enum entries?". Cela semble simple, non ? Mais en pratique, de nombreux débutants (et pas seulement) butent sur ce point.

\n\n

Dans cet article, nous ne nous contenterons pas de donner une réponse toute faite. Nous allons sous le capot de TypeScript et analyserons comment fonctionnent exactement les enum, comment le compilateur les transforme en JavaScript, et pourquoi certaines approches pour obtenir les noms peuvent entraîner des bugs inattendus. Prêts ? C'est parti !

\n\n

Qu'est-ce qu'un enum en TypeScript et pourquoi a-t-on besoin de leurs noms ?

\n\n

Un enum (énumération) est un moyen pratique de définir un ensemble de constantes nommées. En TypeScript, ils peuvent être numériques (par défaut) ou chaînes de caractères. Mais que faire si vous devez obtenir le nom d'une valeur spécifique ? Par exemple, vous recevez d'une API le code d'état 403, et vous voulez afficher à l'utilisateur un message compréhensible "Forbidden".

\n\n
enum HttpStatus {\n  OK = 200,\n  NotFound = 404,\n  Forbidden = 403\n}\n\n// Notre objectif : obtenir le nom "Forbidden" à partir de la valeur 403\n
\n\n

Il semble que TypeScript devrait fournir une méthode intégrée pour cela. Mais non. Il faut écrire sa propre logique. Et c'est là que les choses deviennent intéressantes.

\n\n

La solution "à la va-vite" : Object.keys et Object.values

\n\n

La méthode la plus évidente consiste à utiliser les méthodes Object.keys() ou Object.values(). De nombreux débutants écrivent quelque chose comme ceci :

\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" — ça marche !\n
\n\n

Cela semble logique, non ? Mais si vous essayez ce code sur un enum numérique, une surprise vous attend. Regardons ce que notre HttpStatus devient après compilation.

\n\n

Sous le capot : compilation d'un enum numérique

\n\n

Lorsque TypeScript compile un enum numérique, il crée un objet avec un mappage inverse (reverse mapping). Voici à quoi ressemble le JavaScript compilé :

\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// Au final, l'objet HttpStatus ressemble à ceci :\n// { \n//   "200": "OK", \n//   "404": "NotFound", \n//   "403": "Forbidden", \n//   "OK": 200, \n//   "NotFound": 404, \n//   "Forbidden": 403 \n// }\n
\n\n

Vous voyez l'astuce ? Le compilateur ajoute à la fois des clés numériques et des clés chaînes de caractères. Par conséquent, Object.keys(HttpStatus) retournera non seulement ["OK", "NotFound", "Forbidden"], mais aussi ["200", "404", "403"]. Cela casse la logique de notre solution simple !

\n\n

Pour contourner ce problème, il faut filtrer les clés numériques :

\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

Mais ce code semble bancal. Existe-t-il une meilleure méthode ?

\n\n

Les enum chaînes de caractères : une autre histoire

\n\n

Si vous utilisez des enum chaînes de caractères, le reverse mapping n'est pas créé. Cela simplifie la tâche :

\n\n
enum Direction {\n  Up = "UP",\n  Down = "DOWN",\n  Left = "LEFT",\n  Right = "RIGHT"\n}\n\n// Object.keys(Direction) retournera uniquement ["Up", "Down", "Left", "Right"] — parfait !\n
\n\n

Mais que faire si vous devez obtenir le nom à partir de la valeur ? Le même Object.keys fonctionne parfaitement :

\n\n
function getStringEn                

Blogs

Book Recommendations