Enums & Literal Types
๐ฆ Enums & Literal Types
๐ String Enums
Basic String Enum
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" } function move(direction: Direction) { console.log(`Moving ${direction}`); } move(Direction.Up); // โ "Moving UP" move("UP"); // โ Error! String literal not allowed
Enum Without Explicit Values
If you don't specify values, TypeScript uses the member name:
enum Status { Active, // value is "Active" Inactive, // value is "Inactive" Pending // value is "Pending" } const status: Status = Status.Active; console.log(status); // "Active"
๐ข Numeric Enums
// Numeric enums auto-increment enum Level { Low = 0, Medium = 1, High = 2 } // Or let TypeScript auto-increment enum Priority { Low, // 0 Medium, // 1 High // 2 } // You can also start at any number enum HttpStatus { OK = 200, NotFound = 404, ServerError = 500 }
Reverse Mapping (Numeric Enums Only)
With numeric enums, you can look up the name from the value:
enum Status { Active = 0, Inactive = 1 } // Forward mapping: Status.Active โ 0 console.log(Status.Active); // 0 // Reverse mapping: 0 โ "Active" console.log(Status[0]); // "Active" const code: number = 0; console.log(Status[code]); // "Active"
โก Const Enums
const enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" } function move(direction: Direction) { console.log(direction); } move(Direction.Up); // Compiled JavaScript: // function move(direction) { console.log(direction); } // move("UP"); // Notice: Direction enum disappears! The value "UP" is inlined.
๐ Literal Types
String Literal Types
type Size = "small" | "medium" | "large"; function setSize(size: Size) { console.log(`Size: ${size}`); } setSize("small"); // โ setSize("large"); // โ setSize("huge"); // โ Error! Not in the union
Number Literal Types
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6; function rollDice(roll: DiceRoll) { console.log(`You rolled: ${roll}`); } rollDice(3); // โ rollDice(7); // โ Error! 7 is not 1-6
Boolean Literal Types
type OnOrOff = true | false; // This is actually just boolean, but you can be more specific: type Enabled = true; // Only true is allowed function enable(status: Enabled) { // status can only be true } enable(true); // โ enable(false); // โ Error!
๐ค Enums vs Literal Types
Both can represent restricted values. Which should you use?
| Feature | Enum | Literal Union |
|---|---|---|
| Syntax | enum Direction { Up, Down } | type Direction = "Up" | "Down" |
| Values | Can be numbers or strings | Usually strings (but can be numbers) |
| Reverse Mapping | Yes (for numbers) | No |
| Const Enum Optimization | Yes, zero runtime overhead | Already zero overhead |
| When to Use | Legacy code, reverse mapping needed | Modern code, most new projects |
๐ Real-World Patterns
HTTP Status Codes
// Using const enum const enum HttpStatus { OK = 200, Created = 201, BadRequest = 400, Unauthorized = 401, NotFound = 404, ServerError = 500 } function handleResponse(status: HttpStatus) { switch (status) { case HttpStatus.OK: console.log("Success"); break; case HttpStatus.NotFound: console.log("Not found"); break; } }
Event Types with Literal Union
type Event = | { type: "click"; x: number; y: number } | { type: "scroll"; delta: number } | { type: "keypress"; key: string }; function handleEvent(event: Event) { switch (event.type) { case "click": console.log(`Clicked at ${event.x}, ${event.y}`); break; case "scroll": console.log(`Scrolled ${event.delta}px`); break; case "keypress": console.log(`Pressed ${event.key}`); break; } }
๐ป Coding Challenges
Challenge 1: String Enum
Create a Color enum with at least 5 colors (Red, Green, Blue, Yellow, Purple). Write a function that accepts a color and returns a CSS color code.
- Define the enum with string values
- Create a function that maps colors to hex codes
- Test with all colors
Goal: Practice string enums and mapping to values.
Challenge 2: Literal Type Union
Create a LogLevel type using literal union that represents log levels: "debug", "info", "warn", "error". Write a logger function that outputs with appropriate formatting.
- Define literal union type
- Create logger with different prefixes per level
- Demonstrate exhaustiveness checking
Goal: Practice literal types and discriminated unions.
Challenge 3: Const Enum Optimization
Create a UserRole const enum with Admin, User, Guest. Build a permission checker that uses the const enum. Compare compile output with regular enum.
- Define const enum
- Create hasPermission function
- Understand compile-time inlining
Goal: Understand const enum optimization and when to use it.
๐ Best Practices
Modern TypeScript code prefers literal unions (string | unions). They're simpler, produce the same output, and work better with type inference.
// โ Better type Status = "active" | "inactive" | "pending"; // โ Legacy enum Status { Active = "active", Inactive = "inactive", Pending = "pending" }
If you must use enums, use const enum for zero runtime overhead. The values are inlined during compilation.
๐ฏ What's Next
We've mastered constants and restricted types. Chapter 10 covers Modules & Namespaces โ how to organize code into reusable, maintainable modules and manage scope effectively.