Enums
Learn how to define a set of named constants using TypeScript enums, and when a union of literals might be a better fit.
Reading Time
12 min
Lesson
Lesson 5 of 30
What is an Enum?
An enum (enumeration) defines a set of named constants, making code more readable than scattering raw numbers or strings throughout a codebase.
A Numeric Enum
enum Direction {
Up,
Down,
Left,
Right,
}
let move: Direction = Direction.Up;
console.log(move); // 0 — members auto-increment from 0 by defaultString Enums
String enums require every member to have an explicit value, and are generally easier to debug since logging a member shows a meaningful string instead of a number.
A String Enum
enum Status {
Pending = "PENDING",
Active = "ACTIVE",
Completed = "COMPLETED",
}
function printStatus(status: Status) {
console.log(status);
}
printStatus(Status.Active); // "ACTIVE"Custom Numeric Values
Numeric enum members can start at a custom value, with subsequent members auto-incrementing from there.
Custom Starting Value
enum HttpStatus {
OK = 200,
Created = 201,
BadRequest = 400,
NotFound = 404,
}Numeric vs String Enums
| Numeric Enum | String Enum | |
|---|---|---|
| Default values | Auto-increment from 0 | None — every member needs a value |
| Debug readability | Logs as a number | Logs as a readable string |
| Reverse mapping | Yes (number → name) | No |
An Alternative: Union of String Literals
Many teams prefer a union of string literals over an enum — it requires no extra runtime code, works naturally with plain objects and JSON, and is simpler to reason about.
Union of Literals as an Alternative
type Status = "PENDING" | "ACTIVE" | "COMPLETED";
function printStatus(status: Status) {
console.log(status);
}
printStatus("ACTIVE"); // valid
printStatus("DONE"); // Error: not assignable to type 'Status'Enums Exist at Runtime
Unlike most TypeScript type constructs, a regular enum compiles into a real JavaScript object that exists at runtime — it isn’t erased like interfaces and type aliases are.
Best Practice
Reach for a union of string literals for simple, closed sets of values — reserve enum for cases where you specifically want the extra runtime object or reverse lookup behavior.