How do enums work in TypeScript?
Enums define a set of named constants. TypeScript supports numeric and string enums - but const enums and union types are often better alternatives.
TypeScript
Overview
An `enum` defines a named set of constants, making intent clear and preventing magic values. TypeScript has two main flavors: **numeric** (auto-incremented integers) and **string** (explicit string values). Both compile to JavaScript objects, which has tradeoffs.
Key Points
- •Numeric enum: values are 0, 1, 2… by default. You can set a starting value.
- •String enum: each member must be explicitly initialised with a string literal.
- •`const enum` is inlined at compile time (no runtime object generated) - more efficient.
- •A popular alternative: a union of string literals (`type Direction = "Up" | "Down"`) - no compiled output.
- •Enums are one of the few TypeScript features that emit runtime JavaScript code; string literal unions do not.
Examples
Numeric enum
typescriptenum Direction {
Up, // 0
Down, // 1
Left, // 2
Right, // 3
}
console.log(Direction.Up); // 0
console.log(Direction[0]); // 'Up' (reverse mapping)
function move(d: Direction) { ... }
move(Direction.Left);String enum (recommended)
typescriptenum Status {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
Pending = 'PENDING',
}
const userStatus: Status = Status.Active;
console.log(userStatus); // 'ACTIVE'
// String enums have no reverse mapping, which avoids some pitfallsconst enum (zero runtime cost)
typescriptconst enum HttpMethod {
Get = 'GET',
Post = 'POST',
Put = 'PUT',
Delete = 'DELETE',
}
// TypeScript inlines the value at every usage - no JS object emitted
const method = HttpMethod.Get;
// Compiled to: const method = 'GET';const enums cannot be used across module boundaries with isolatedModules.
Union type alternative (often preferred)
typescript// No runtime cost, simpler, works everywhere
type Direction = 'Up' | 'Down' | 'Left' | 'Right';
type Status = 'active' | 'inactive' | 'pending';
function move(dir: Direction) { ... }
move('Up'); // works directly, no Direction.Up neededPro Tip
In modern TypeScript, prefer string literal union types over enums for most cases: `type Status = "active" | "inactive"`. They have zero runtime cost, are easier to use, and integrate better with JSON APIs. Use enums when you need an associated value (like an HTTP status code number) or want to iterate over the members at runtime.