TypeScript Enums
An enum (short for enumeration) defines a set of named constants. Instead of using raw numbers or magic strings scattered throughout the code, an enum groups related values under a meaningful name. This makes code more readable, prevents typos, and makes the intent of each value clear.
Why Enums?
Without enum (hard to read): let status = 2; ← What does 2 mean? With enum (clear and safe): let status = OrderStatus.Shipped; ← Instantly understandable Enum definition: +------------------+-------+ | Name | Value | +------------------+-------+ | OrderStatus.New = 0 | | OrderStatus.Packed = 1 | | OrderStatus.Shipped = 2 | | OrderStatus.Delivered=3 | +------------------+-------+
Numeric Enums
Numeric enums assign numbers to each member automatically, starting from 0. The starting value can be customized and subsequent members increment from there.
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
let move: Direction = Direction.Up;
console.log(move); // 0
console.log(Direction.Left); // 2
Change the starting value:
enum StatusCode {
OK = 200,
Created = 201,
BadRequest = 400,
Unauthorized = 401,
NotFound = 404,
ServerError = 500
}
console.log(StatusCode.OK); // 200
console.log(StatusCode.NotFound); // 404
String Enums
String enums assign string values to each member. Each member must be explicitly assigned. String enums produce more readable output in logs and debugging compared to numeric enums.
enum OrderStatus {
Pending = "PENDING",
Confirmed = "CONFIRMED",
Shipped = "SHIPPED",
Delivered = "DELIVERED",
Cancelled = "CANCELLED"
}
let currentStatus: OrderStatus = OrderStatus.Shipped;
console.log(currentStatus); // SHIPPED
Using Enums in Functions
enum Season {
Spring = "SPRING",
Summer = "SUMMER",
Autumn = "AUTUMN",
Winter = "WINTER"
}
function getActivity(season: Season): string {
if (season === Season.Summer) return "Go swimming";
if (season === Season.Winter) return "Stay indoors";
if (season === Season.Spring) return "Go for a walk";
return "Collect leaves";
}
console.log(getActivity(Season.Summer)); // Go swimming
console.log(getActivity(Season.Winter)); // Stay indoors
Const Enums
Adding the const keyword before an enum creates a const enum. TypeScript replaces each enum reference with its actual value during compilation, removing the enum object from the compiled JavaScript. This results in smaller output and faster execution.
const enum PaymentMethod {
Cash = "CASH",
Card = "CARD",
UPI = "UPI",
NetBanking = "NET_BANKING"
}
let payment: PaymentMethod = PaymentMethod.UPI;
console.log(payment); // "UPI" — TypeScript inlines the value directly
Reverse Mapping in Numeric Enums
Numeric enums support reverse mapping — getting the name from its value. String enums do not support this feature.
enum Weekday {
Monday = 1,
Tuesday,
Wednesday,
Thursday,
Friday
}
console.log(Weekday[1]); // "Monday" (value → name)
console.log(Weekday["Tuesday"]); // 2 (name → value)
console.log(Weekday[3]); // "Wednesday"
Heterogeneous Enums
TypeScript allows mixing number and string values in the same enum, though this is uncommon and generally not recommended unless a specific use case demands it.
enum MixedEnum {
Active = 1,
Status = "ACTIVE"
}
Enum in Switch Statement
enum TrafficLight {
Red = "RED",
Yellow = "YELLOW",
Green = "GREEN"
}
function getInstruction(light: TrafficLight): string {
switch (light) {
case TrafficLight.Red: return "Stop";
case TrafficLight.Yellow: return "Slow down";
case TrafficLight.Green: return "Go";
default: return "Unknown signal";
}
}
console.log(getInstruction(TrafficLight.Red)); // Stop
console.log(getInstruction(TrafficLight.Green)); // Go
Enum Types Comparison
| Feature | Numeric Enum | String Enum | Const Enum |
|---|---|---|---|
| Default values | Auto-assigned (0, 1, 2...) | Must be explicit | Same as chosen type |
| Reverse mapping | Supported | Not supported | Not supported |
| Compiled output | Object in JS | Object in JS | Inlined values (no object) |
| Readability in logs | Numbers (less clear) | Strings (very clear) | Strings (very clear) |
| Best for | Bit flags, HTTP codes | Status values, roles | Performance-critical code |
Practical Example
// Student result management using enums
enum ResultStatus {
Passed = "PASSED",
Failed = "FAILED",
Absent = "ABSENT",
Pending = "PENDING"
}
enum ExamGrade {
APlus = "A+",
A = "A",
B = "B",
C = "C",
F = "F"
}
function evaluateStudent(name: string, marks: number): void {
let status: ResultStatus;
let grade: ExamGrade;
if (marks < 0) {
status = ResultStatus.Absent;
grade = ExamGrade.F;
} else if (marks >= 90) {
status = ResultStatus.Passed;
grade = ExamGrade.APlus;
} else if (marks >= 75) {
status = ResultStatus.Passed;
grade = ExamGrade.A;
} else if (marks >= 40) {
status = ResultStatus.Passed;
grade = ExamGrade.B;
} else {
status = ResultStatus.Failed;
grade = ExamGrade.F;
}
console.log(name + " | Status: " + status + " | Grade: " + grade);
}
evaluateStudent("Lata", 92); // Lata | Status: PASSED | Grade: A+
evaluateStudent("Raju", 55); // Raju | Status: PASSED | Grade: B
evaluateStudent("Geeta", 30); // Geeta | Status: FAILED | Grade: F
