So erhält man Enum-Namen in TypeScript: Magie unter der Haube

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Die ewige Frage auf Stack Overflow

\n\n

Haben Sie sich jemals gefragt, wie erfahrene TypeScript-Entwickler die Namen von enum-Werten erhalten? Wenn Sie auf Stack Overflow waren, haben Sie sicherlich die Frage mit tausenden von Aufrufen gesehen: "How to get names of enum entries?". Es scheint einfach, aber in der Praxis stolpern viele Anfänger (und nicht nur sie) über diese Stelle.

\n\n

In diesem Artikel geben wir nicht nur eine fertige Antwort. Wir schauen unter die Haube von TypeScript und analysieren, wie enum genau funktioniert, wie der Compiler sie in JavaScript umwandelt und warum einige Ansätze zum Abrufen von Namen zu unerwarteten Fehlern führen können. Bereit? Los geht's!

\n\n

Was ist ein Enum in TypeScript und wozu braucht man ihre Namen?

\n\n

Ein Enum (Aufzählung) ist eine praktische Möglichkeit, einen Satz benannter Konstanten zu definieren. In TypeScript gibt es numerische (standardmäßig) und stringbasierte Enums. Aber was tun, wenn Sie den Namen eines bestimmten Werts benötigen? Zum Beispiel erhalten Sie von einer API den Statuscode 403 und möchten dem Benutzer eine verständliche Meldung "Forbidden" anzeigen.

\n\n
enum HttpStatus {\n  OK = 200,\n  NotFound = 404,\n  Forbidden = 403\n}\n\n// Unsere Aufgabe: Den Namen "Forbidden" zum Wert 403 erhalten\n
\n\n

Es scheint, dass TypeScript eine eingebaute Methode dafür bereitstellen sollte. Aber nein. Man muss seine eigene Logik schreiben. Und hier wird es interessant.

\n\n

Die "einfache" Lösung: Object.keys und Object.values

\n\n

Der naheliegendste Weg ist die Verwendung der Methoden Object.keys() oder Object.values(). Viele Anfänger schreiben so etwas:

\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" — funktioniert!\n
\n\n

Sieht logisch aus, oder? Aber wenn Sie diesen Code mit einem numerischen Enum ausprobieren, erwartet Sie eine Überraschung. Schauen wir uns an, wozu unser HttpStatus kompiliert wird.

\n\n

Unter der Haube: Kompilierung eines numerischen Enums

\n\n

Wenn TypeScript ein numerisches Enum kompiliert, erstellt es ein Objekt mit Reverse Mapping. So sieht der kompilierte JavaScript-Code aus:

\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// Das HttpStatus-Objekt sieht letztendlich so aus:\n// { \n//   "200": "OK", \n//   "404": "NotFound", \n//   "403": "Forbidden", \n//   "OK": 200, \n//   "NotFound": 404, \n//   "Forbidden": 403 \n// }\n
\n\n

Sehen Sie den Trick? Der Compiler fügt sowohl Zahlen- als auch String-Schlüssel hinzu. Daher gibt Object.keys(HttpStatus) nicht nur ["OK", "NotFound", "Forbidden"] zurück, sondern auch ["200", "404", "403"]. Das zerstört die Logik unserer einfachen Lösung!

\n\n

Um dies zu umgehen, müssen wir die numerischen Schlüssel herausfiltern:

\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

Aber dieser Code wirkt wie eine Krücke. Gibt es einen besseren Weg?

\n\n

String-Enums: Eine andere Geschichte

\n\n

Wenn Sie stringbasierte Enums verwenden, wird kein Reverse Mapping erstellt. Das vereinfacht die Aufgabe:

\n\n
enum Direction {\n  Up = "UP",\n  Down = "DOWN",\n  Left = "LEFT",\n  Right = "RIGHT"\n}\n\n// Object.keys(Direction) gibt nur ["Up", "Down", "Left", "Right"] zurück — perfekt!\n
\n\n

Aber was, wenn Sie den Namen zu einem Wert benötigen? Derselbe Object.keys funktioniert hervorragend:

\n\n
function getStringEn                

Blogs

Buchempfehlungen