Typen
Enums in TypeScript: Aufzaehlungstypen richtig einsetzen
Lerne, wie numerische und String-Enums in TypeScript funktionieren, wo ihre Grenzen liegen und wann Alternativen wie Const-Objekte besser geeignet sind.
Inhalt
Enums in TypeScript: Aufzaehlungstypen richtig einsetzen
Enums sind ein TypeScript-Feature, mit dem du eine benannte Menge von Konstanten definieren kannst. Sie machen Code lesbarer und verhindern magische Zahlen oder Strings, die ohne Kontext schwer zu verstehen sind. Gleichzeitig gibt es Fallstricke und moderne Alternativen, die es wert sind, bekannt zu sein.
Numerische Enums
Die einfachste Form ist der numerische Enum. TypeScript weist jedem Member automatisch einen Wert zu, beginnend bei 0:
enum Himmelsrichtung {
Nord,
Ost,
Sued,
West,
}
const kurs: Himmelsrichtung = Himmelsrichtung.Nord;
console.log(kurs); // 0
Du kannst den Startwert aendern:
enum Prioritaet {
Niedrig = 1,
Mittel = 2,
Hoch = 3,
}
Oder einzelne Werte explizit setzen, die restlichen werden dann hochgezaehlt:
enum HttpStatus {
Ok = 200,
NichtGefunden = 404,
ServerFehler = 500,
}
Das Reverse-Mapping bei numerischen Enums
Numerische Enums erzeugen ein bidirektionales Mapping. Das bedeutet, du kannst sowohl vom Namen auf den Wert als auch vom Wert auf den Namen zugreifen:
enum Farbe {
Rot,
Gruen,
Blau,
}
console.log(Farbe.Rot); // 0
console.log(Farbe[0]); // "Rot"
console.log(Farbe[Farbe.Rot]); // "Rot"
Das Reverse-Mapping kann nuetzlich sein, ist aber auch eine Quelle von Verwirrung, besonders wenn man mit String-Enums vergleicht.
String Enums
String-Enums erfordern explizite Werte fuer jeden Member, bieten aber mehr Klarheit im Debugging:
enum Benutzerrole {
Admin = "ADMIN",
Redakteur = "REDAKTEUR",
Leser = "LESER",
}
function pruefeZugriff(rolle: Benutzerrole): boolean {
return rolle === Benutzerrole.Admin;
}
String-Enums haben kein Reverse-Mapping. Der tatsaechliche Wert erscheint direkt in Log-Ausgaben und Netzwerkantworten, was die Lesbarkeit verbessert.
Heterogene Enums
Technisch erlaubt TypeScript Enums mit gemischten Typen, aber das sollte man in der Praxis vermeiden:
// Moeglich, aber nicht empfohlen
enum Gemischt {
Nein = 0,
Ja = "JA",
}
Gemischte Enums machen den Code schwerer vorhersagbar und sollten nur in speziellen Faellen eingesetzt werden.
Const Enums
const enum ist eine optimierte Variante, bei der der Compiler die Enum-Referenzen direkt durch Werte ersetzt und kein JavaScript-Objekt erzeugt:
const enum Richtung {
Auf,
Ab,
Links,
Rechts,
}
const bewegung = Richtung.Auf;
// Wird zu: const bewegung = 0;
Const Enums sind effizienter, funktionieren aber nicht mit isolierter Kompilierung (wie bei Tools, die Dateien einzeln transpilieren). Bei Projekten mit Babel oder esbuild sollte man deshalb auf regulaere Enums oder Const-Objekte zurueckgreifen.
Enums als Typen in Funktionen
Enums koennen direkt als Typannotation verwendet werden:
enum Ampel {
Rot = "ROT",
Gelb = "GELB",
Gruen = "GRUEN",
}
function reagiereAufAmpel(signal: Ampel): string {
switch (signal) {
case Ampel.Rot:
return "Anhalten";
case Ampel.Gelb:
return "Vorsicht";
case Ampel.Gruen:
return "Fahren";
}
}
TypeScript warnt, wenn nicht alle Enum-Member im Switch behandelt werden, wenn noImplicitReturns und strictNullChecks aktiviert sind.
Die moderne Alternative: Const-Objekte mit as const
Viele TypeScript-Teams bevorzugen heute Const-Objekte statt Enums:
const Benutzerrole = {
Admin: "ADMIN",
Redakteur: "REDAKTEUR",
Leser: "LESER",
} as const;
type Benutzerrole = (typeof Benutzerrole)[keyof typeof Benutzerrole];
function pruefeZugriff(rolle: Benutzerrole): boolean {
return rolle === Benutzerrole.Admin;
}
Diese Alternative erzeugt kein zusaetzliches JavaScript, ist tree-shakeable und verhaelt sich wie normales JavaScript-Objekt. Der Typ wird aus dem Objekt abgeleitet. Probiere diesen Ansatz im Playground aus, um den Unterschied im transpilierten JavaScript direkt zu sehen.
Wann Enums, wann Const-Objekte?
Beide Ansaetze haben ihre Berechtigung:
// Enums eignen sich gut fuer:
// - Abgeschlossene Mengen, die explizit als Enum kommuniziert werden sollen
// - Environments, wo TypeScript vollstaendig die Kontrolle hat (kein Babel)
// - Wenn Reverse-Mapping benoetigt wird
// Const-Objekte eignen sich gut fuer:
// - Projekte mit gemischten Build-Tools
// - Wenn das ausgegebene JavaScript minimal sein soll
// - Wenn du den Wert direkt als String-Literal verwenden moechtest
Namespacing mit Enums
Enums koennen auch als Namespace fuer verwandte Konstanten dienen:
enum Mathematik {
Pi = 3.14159,
E = 2.71828,
GoldenerSchnitt = 1.61803,
}
const umfang = 2 * Mathematik.Pi * 5;
Das ist eine saubere Alternative zum Anlegen eines eigenen Objekts fuer Konstanten.
Fazit
Enums sind ein nuetzliches TypeScript-Feature fuer benannte Konstantenmengen. Numerische Enums sind einfach und compact, String-Enums sind lesbarer und sicherer fuer serialisierte Daten. Const Enums optimieren die Ausgabe, haben aber Einschraenkungen. Fuer moderne Projekte mit verschiedenen Build-Tools ist das Const-Objekt-Muster oft die bessere Wahl. In jedem Fall lohnt es sich, die Vor- und Nachteile im eigenen Projektkontext abzuwaegen.
Häufige Fragen
Was ist der Unterschied zwischen numerischen und String-Enums?
Numerische Enums weisen jedem Member automatisch einen ganzzahligen Wert zu, beginnend bei 0. String-Enums erfordern explizite String-Werte fuer jeden Member und sind im Debugging lesbarer, weil der tatsaechliche Wert erkennbar ist.
Sollte ich Enums oder Const-Objekte verwenden?
In modernem TypeScript bevorzugen viele Teams Const-Objekte mit 'as const', weil diese kein zusaetzliches JavaScript erzeugen, tree-shakeable sind und sich natuerlicher anfuehlen. Enums sind weiterhin sinnvoll, wenn du explizit eine abgeschlossene Menge von Werten modellieren willst.
Was sind Const Enums?
Const Enums werden zur Kompilierzeit vollstaendig aufgeloest und erzeugen kein JavaScript-Objekt. Sie sind effizienter als regulaere Enums, koennen aber nicht dynamisch aufgerufen werden und haben Einschraenkungen bei isolierter Kompilierung.
Quellen
Über die Autorenschaft
Mateusz Viola
Betreiber und redaktionelle Verantwortung typescript-playground.de
Themengebiet: Mathematik, Kalenderrechnung, Schaltjahre, Statistik und ISO 8601
Mehr über Mateusz Viola →Verwandte Artikel
Grundlagen
Was ist TypeScript? Eine Einführung in die typisierte JavaScript-Erweiterung
TypeScript erweitert JavaScript um statische Typen und macht große Codebases wartbarer. Lerne die Grundlagen, die Geschichte und die wichtigsten Vorteile von TypeScript.
Lesezeit 7 Min.
Grundlagen
TypeScript vs. JavaScript: Die wichtigsten Unterschiede im Überblick
TypeScript und JavaScript unterscheiden sich grundlegend in der Typprüfung, Werkzeugunterstützung und Wartbarkeit. Dieser Ratgeber erklärt die Unterschiede und hilft bei der Wahl der richtigen Sprache.
Lesezeit 8 Min.
Typen
TypeScript Typen Grundlagen: string, number, boolean und mehr
Die primitiven Typen string, number und boolean sind das Fundament von TypeScript. Dieser Ratgeber erklärt alle grundlegenden Typen mit praktischen Beispielen.
Lesezeit 9 Min.