Fortgeschritten102025-01-15

TypeScript Enums - Benannte Konstanten

Lerne Enums in TypeScript für typsichere Konstanten. Numeric, String und Const Enums erklärt.

#typescript#enums#constants

TypeScript Enums - Benannte Konstanten

Enums definieren benannte Konstanten-Sets in TypeScript.

Numeric Enums

Standard Enum mit Zahlen:

enum Direction {
  Up,     // 0
  Down,   // 1
  Left,   // 2
  Right   // 3
}

let dir: Direction = Direction.Up
console.log(dir) // 0

Custom Start Value

enum Status {
  Active = 1,
  Inactive = 2,
  Pending = 3
}

console.log(Status.Active) // 1

Auto-Increment

enum HttpStatus {
  OK = 200,
  Created,      // 201
  Accepted,     // 202
  NoContent = 204,
  BadRequest = 400,
  Unauthorized, // 401
  Forbidden     // 402
}

String Enums

Enums mit String-Werten:

enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

let color: Color = Color.Red
console.log(color) // "RED"

Vorteile:

  • ✅ Bessere Lesbarkeit in Logs
  • ✅ Debugging freundlicher
  • ✅ Keine Magic Numbers

Real-World Beispiel

enum UserRole {
  Admin = "ADMIN",
  Moderator = "MODERATOR",
  User = "USER",
  Guest = "GUEST"
}

function hasPermission(role: UserRole): boolean {
  return role === UserRole.Admin || role === UserRole.Moderator
}

hasPermission(UserRole.Admin) // true
hasPermission(UserRole.Guest) // false

Heterogeneous Enums

Mix aus Strings und Numbers (nicht empfohlen):

enum Mixed {
  No = 0,
  Yes = "YES"
}

⚠️ Nicht empfohlen - verwirrt mehr als es hilft!

Const Enums

Performance-optimierte Enums:

const enum Direction {
  Up,
  Down,
  Left,
  Right
}

let dir = Direction.Up

// Kompiliert zu:
let dir = 0 /* Direction.Up */

Unterschied zu normalen Enums:

  • Wird komplett wegoptimiert
  • Kein JavaScript-Objekt zur Laufzeit
  • Kleinere Bundle-Size

Reverse Mapping

Bei Numeric Enums funktioniert Reverse Lookup:

enum Status {
  Active = 1,
  Inactive = 2
}

console.log(Status[1]) // "Active"
console.log(Status[2]) // "Inactive"

// Generiertes JavaScript:
var Status;
(function (Status) {
    Status[Status["Active"] = 1] = "Active";
    Status[Status["Inactive"] = 2] = "Inactive";
})(Status || (Status = {}));

String Enums haben KEIN Reverse Mapping!

Enums als Types

enum UserRole {
  Admin = "ADMIN",
  User = "USER"
}

interface User {
  name: string
  role: UserRole
}

const user: User = {
  name: "Max",
  role: UserRole.Admin
}

function checkRole(user: User): void {
  switch (user.role) {
    case UserRole.Admin:
      console.log("Admin access")
      break
    case UserRole.User:
      console.log("User access")
      break
  }
}

Enum vs Union Types

Enum Approach

enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE"
}

function setStatus(status: Status): void {
  console.log(status)
}

setStatus(Status.Active)

Union Type Approach

type Status = "ACTIVE" | "INACTIVE"

function setStatus(status: Status): void {
  console.log(status)
}

setStatus("ACTIVE")

Vergleich

| Feature | Enum | Union Type | |---------|------|------------| | Runtime Object | ✅ Ja | ❌ Nein | | Autocomplete | ✅ Ja | ✅ Ja | | Bundle Size | Größer | Kleiner | | String Literals | ❌ Nein | ✅ Ja | | Refactoring | ✅ Einfach | ⚠️ Schwieriger |

Empfehlung:

  • Enums: Wenn Runtime-Zugriff nötig
  • Union Types: Für einfache String-Konstanten
Real-World API Status Codes
enum HttpStatus {
  // Success
  OK = 200,
  Created = 201,
  NoContent = 204,

  // Client Errors
  BadRequest = 400,
  Unauthorized = 401,
  Forbidden = 403,
  NotFound = 404,
  Conflict = 409,

  // Server Errors
  InternalServerError = 500,
  BadGateway = 502,
  ServiceUnavailable = 503
}

interface ApiResponse<T> {
  status: HttpStatus
  data?: T
  error?: string
}

function createResponse<T>(
  status: HttpStatus,
  data?: T,
  error?: string
): ApiResponse<T> {
  return { status, data, error }
}

// Usage
const success = createResponse(HttpStatus.OK, { user: "Max" })
const error = createResponse(HttpStatus.NotFound, undefined, "User not found")

// Type-Safe Switch
function handleResponse(response: ApiResponse<any>): void {
  switch (response.status) {
    case HttpStatus.OK:
    case HttpStatus.Created:
      console.log("Success:", response.data)
      break
    case HttpStatus.NotFound:
      console.error("Not found:", response.error)
      break
    case HttpStatus.InternalServerError:
      console.error("Server error:", response.error)
      break
    default:
      console.warn("Unhandled status:", response.status)
  }
}

📝 Quiz

Was ist der Hauptunterschied zwischen const enum und normalem enum?

Tipps & Tricks

Enum Helpers

enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

// Alle Keys als Array
const colorKeys = Object.keys(Color) as (keyof typeof Color)[]

// Alle Values als Array
const colorValues = Object.values(Color)

// Check ob Wert im Enum
function isColor(value: string): value is Color {
  return Object.values(Color).includes(value as Color)
}

isColor("RED") // true
isColor("YELLOW") // false

Computed Enum Members

enum FileAccess {
  None = 0,
  Read = 1 << 0,      // 1
  Write = 1 << 1,     // 2
  ReadWrite = Read | Write,  // 3
  Execute = 1 << 2    // 4
}

const hasRead = FileAccess.ReadWrite & FileAccess.Read // 1 (true)

Enum als Object Keys

enum Role {
  Admin = "ADMIN",
  User = "USER"
}

type Permissions = {
  [key in Role]: string[]
}

const permissions: Permissions = {
  [Role.Admin]: ["read", "write", "delete"],
  [Role.User]: ["read"]
}

Häufige Fehler

Fehler 1: String Enum ohne Werte

FALSCH:

enum Status {
  Active,    // OK: 0
  Inactive,  // OK: 1
  Pending = "PENDING",
  Deleted    // ❌ Error: muss initialisiert werden
}

RICHTIG:

enum Status {
  Active = "ACTIVE",
  Inactive = "INACTIVE",
  Pending = "PENDING",
  Deleted = "DELETED"
}

Fehler 2: Reverse Mapping bei String Enums erwarten

FALSCH:

enum Color {
  Red = "RED"
}

console.log(Color["RED"]) // undefined (nicht "Red")

VERSTEHEN:

// Nur bei Numeric Enums:
enum Status {
  Active = 1
}

console.log(Status[1]) // "Active" ✅

Fehler 3: Enum mit Dynamic Values

FALSCH:

const apiUrl = "https://api.com"

enum Config {
  ApiUrl = apiUrl // ❌ Error: muss constant sein
}

RICHTIG:

const enum Config {
  ApiUrl = "https://api.com"
}

// Oder besser:
const config = {
  apiUrl: "https://api.com"
} as const
🎯

Zusammenfassung

Du hast gelernt:

  • ✅ Numeric Enums mit Auto-Increment
  • ✅ String Enums für bessere Lesbarkeit
  • ✅ Const Enums für Performance
  • ✅ Reverse Mapping bei Numeric Enums
  • ✅ Enum vs Union Types
  • ✅ Enums in Switch Statements

Key Takeaways:

  • String Enums > Numeric Enums (Lesbarkeit)
  • Const Enums für Performance
  • Union Types als Alternative
  • Keine Heterogeneous Enums verwenden
  • Enums für Runtime-Zugriff

Nächste Schritte

Als Nächstes lernst du:

  • Type Guards und Narrowing
  • Advanced Types
  • TypeScript mit React
  • Best Practices

Viel Erfolg! 🚀

TypeScriptLektion 9 von 15
60% abgeschlossen
Lektion abgeschlossen!

Gut gemacht! 🎉

Du hast "TypeScript Enums - Benannte Konstanten" abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten