šŸ“ Sign Up | šŸ” Log In

← Root | ↑ Up

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ šŸ“„ typescript/enums │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

╔══════════════════════════════════════════════════════════════════════════════════════════════╗
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘

TypeScript Enums

TypeScript enums let you name related constants with a compact syntax while keeping compile-time checking and JavaScript output. They compile to JavaScript objects, so you can reference them at runtime and inspect their values.

Numeric Enums

enum Direction {
  Up,              // 0
  Down,            // 1
  Left = 10,
  Right            // 11 (auto-increment)
}

let dir: Direction = Direction.Up;

Key traits:

  • Members without an initializer auto-increment from 0 or the prior numeric value.
  • Reverse mapping is generated in the emitted JS object (Direction[0] === "Up").
  • You can explicitly set numbers or use computed numeric expressions (must resolve at compile time).

String Enums

enum Role {
  Admin = "admin",
  Staff = "staff"
}

Highlights:

  • Require an initializer; values stay as strings in the emitted code.
  • No reverse mapping is created, which keeps the output smaller.
  • Helpful when you need readable serialized values (APIs, logging, storage).

Const Enums

const enum Status {
  Loading,
  Ready,
  Error
}

const message = Status.Ready; // compiled to literal 1

Use const enum to inline literal values and erase the enum object from emitted JavaScript. This reduces bundle size, but you lose runtime introspection. Avoid when you need reverse mapping or dynamic access.

Bundlers that perform isolated transpilation (ts-node/register, swc, babel) may not support const enums unless they run the TypeScript compiler pipeline. Consider preserveConstEnums if you must keep the enum object in JS while still declaring const enum.

Ambient Enums

Declare shape-only enums in .d.ts files with the declare enum syntax when the values come from external scripts. Ambient members default to numbers and allow constant or computed initializers. The compiler does not emit code for ambient enums.

Heterogeneous Enums (Rarely Useful)

enum Result {
  Ok = 1,
  Failure = "fail"
}

Mixing strings and numbers is legal but confusing. Prefer distinct enums or union types instead.

Enums vs Union Types

Union literals are often more ergonomic when you do not need runtime access:

type Direction = "up" | "down" | "left" | "right";
  • Union literals do not emit JavaScript, so they are dead-code-elimination friendly.
  • Use unions when you only need static checking (e.g., discriminated unions in reducers).
  • Choose enums when you require runtime metadata, iteration, or interop with existing JS code.

Iterating and Interop

Because numeric enums are actual objects, you can iterate keys:

for (const key in Direction) {
  if (isNaN(Number(key))) {
    console.log(key); // "Up", "Down", ...
  }
}

String enums only expose named keys, so iteration is simpler:

Object.values(Role); // ["admin", "staff"]

Best Practices

  • Prefer const enum or union literals in performance-sensitive code to avoid extra objects.
  • Give enums descriptive names; the generated property names leak into stack traces and telemetry.
  • Avoid exporting ambient enums from .d.ts unless the runtime truly provides them.
  • When serializing, ensure you use string enums or map numeric values to stable formats.
  • Combine enums with discriminated unions by exporting both the enum and a type alias: type Status = StatusEnum.Loading | StatusEnum.Ready | StatusEnum.Error;.

Troubleshooting

  • Enum member must have initializer: string enums require an explicit value.
  • Cannot access 'X' before initialization: circular dependencies between enums and other values can cause runtime ReferenceError. Hoist enums or refactor modules.
  • Reverse mapping doubles the property count in numeric enums; use string enums or unions to keep output slim.
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•

← Root | ↑ Up