TypeScript Enums vs Const Enums vs Union Types
Also Known As
enum TypeScript
const enum
string union
union type enum
TL;DR
Three ways to define a set of named constants in TypeScript — regular enums emit JavaScript, const enums are inlined at compile time, and union types are the idiomatic zero-cost alternative.
Explanation
Regular enum: generates JavaScript object, supports reverse mapping (Direction[0] === 'Up'). Const enum: fully inlined at compile time — zero JavaScript generated, faster but no runtime access. String union type: type Direction = 'Up' | 'Down' — no JavaScript emitted, readable, tree-shakeable, and more compatible with JSON APIs. The TypeScript community trend: prefer string union types over enums for most cases; use const enums only when performance is critical and runtime access is not needed; avoid regular numeric enums (they allow invalid values).
Common Misconception
✗ Enums are always better than union types because they are explicit — string union types are fully type-safe, produce no JavaScript, work perfectly with JSON, and are the idiomatic TypeScript approach.
Why It Matters
A numeric enum (enum Status { Active = 0 }) allows Status[99] at runtime with no error — a string union type Status = 'active' | 'inactive' makes invalid values a compile-time error and produces cleaner JSON.
Common Mistakes
- Numeric enums in APIs — JSON serialises as numbers, not readable names.
- Regular enums where const enums or union types would be better — unnecessary JavaScript overhead.
- Mixing enum and non-enum values — direction: Direction | null requires careful handling.
- Using enum as a namespace — use a regular object const as a namespace instead.
Code Examples
✗ Vulnerable
// Numeric enum — allows invalid values, generates JS:
enum Direction { Up, Down, Left, Right }
const d: Direction = 99; // No error! 99 is not a valid direction
JSON.stringify(Direction.Up); // '0' — not readable
// Regular enum generates runtime JS object:
// var Direction;
// Direction[Direction.Up = 0] = 'Up'; ...
✓ Fixed
// String union — zero JS, type-safe, readable JSON:
type Direction = 'Up' | 'Down' | 'Left' | 'Right';
const d: Direction = 'Invalid'; // Compile error!
JSON.stringify('Up'); // 'Up' — readable
// Const enum — inlined, no JS:
const enum Color { Red = 'red', Blue = 'blue' }
const c = Color.Red; // Compiled to: const c = 'red'
// Object const as namespace when runtime needed:
export const Direction = { Up: 'up', Down: 'down' } as const;
export type Direction = typeof Direction[keyof typeof Direction];
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
16 Mar 2026
Edited
22 Mar 2026
Views
77
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
Perplexity 1
Perplexity 40
Amazonbot 13
ChatGPT 9
Google 5
Unknown AI 4
Ahrefs 2
Also referenced
How they use it
crawler 71
crawler_json 1
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: Low
⚡ Quick Fix
Prefer const enums or union types over regular enums — regular enums compile to JavaScript objects with runtime overhead; const enums are erased and union types need no runtime representation
📦 Applies To
typescript 2.0
web
cli
🔗 Prerequisites
🔍 Detection Hints
Regular enum when const enum or string union type would avoid runtime overhead; numeric enum with string values accessed at runtime
Auto-detectable:
✓ Yes
typescript
eslint
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Medium
Context: File