Enums
## Learning Objectives
- Create and use enums
- Understand numeric and string enums
- Use const enums for performance
- Work with computed values
- Master enum methods
## Basic Enums
### Numeric Enums
```typescript
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
let dir: Direction = Direction.Up;
console.log(dir); // 0
```
### With Initial Values
```typescript
enum Status {
Pending = 1,
Active = 2,
Completed = 4,
Failed = 8
}
console.log(Status.Pending); // 1
console.log(Status.Active); // 2
```
### Auto-Increment
```typescript
enum Color {
Red = 1,
Green, // 2
Blue // 3
}
console.log(Color.Red); // 1
console.log(Color.Green); // 2
console.log(Color.Blue); // 3
```
## String Enums
### Declaration
```typescript
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
let dir: Direction = Direction.Up;
console.log(dir); // "UP"
```
### Why String Enums?
- More explicit and readable
- Good for debugging
- No auto-increment behavior
## Using Enums
### In Switch
```typescript
enum Status {
Pending,
Active,
Completed
}
function getStatusMessage(status: Status): string {
switch (status) {
case Status.Pending:
return "Waiting...";
case Status.Active:
return "In progress...";
case Status.Completed:
return "Done!";
default:
return "Unknown";
}
}
```
### As Return Types
```typescript
enum Result {
Success,
Error
}
function divide(a: number, b: number): { result: number; status: Result } {
if (b === 0) {
return { result: 0, status: Result.Error };
}
return { result: a / b, status: Result.Success };
}
```
## Reverse Mapping
Numeric enums can get value from key:
```typescript
enum Color {
Red = 1,
Green = 2,
Blue = 3
}
console.log(Color.Red); // 1
console.log(Color[1]); // "Red"
console.log(Color[2]); // "Green"
```
## Const Enums
### Const Enum Declaration
```typescript
const enum Direction {
Up,
Down,
Left,
Right
}
```
### Benefits
- Inlined at compile time
- No runtime code generated
- Better performance
### Usage
```typescript
const enum Directions {
Up = "UP",
Down = "DOWN"
}
let dir = Directions.Up; // Inlined as "UP"
```
### Generated JavaScript
```typescript
// TypeScript
const enum Direction { Up, Down }
let dir = Direction.Up;
// Generated JavaScript
let dir = 0; // Inlined!
```
## Heterogeneous Enums
Mix of string and number (avoid when possible):
```typescript
enum BooleanLike {
No = 0,
Yes = "YES"
}
```
## Enum with Methods
```typescript
enum Operation {
Add = 1,
Subtract = 2,
Multiply = 3,
Divide = 4
}
function calculate(a: number, b: number, op: Operation): number {
switch (op) {
case Operation.Add:
return a + b;
case Operation.Subtract:
return a - b;
case Operation.Multiply:
return a * b;
case Operation.Divide:
return a / b;
default:
return 0;
}
}
calculate(10, 5, Operation.Add); // 15
calculate(10, 5, Operation.Multiply); // 50
```
## Object-like Enums
When enum values are constant:
```typescript
const enum HttpStatus {
Ok = 200,
Created = 201,
BadRequest = 400,
Unauthorized = 401,
NotFound = 404
}
function checkStatus(code: number): string {
if (code === HttpStatus.Ok) return "Success";
if (code === HttpStatus.NotFound) return "Not found";
return "Unknown";
}
```
## Union with Enums
```typescript
enum ShapeKind {
Circle,
Square
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
side: number;
}
type Shape = Circle | Square;
```
## Enum in Interfaces
```typescript
interface Event {
type: enum {
Click,
Hover,
Focus
};
target: string;
}
function handleEvent(event: Event): void {
if (event.type === Event.type.Click) {
// Handle click
}
}
```
## Exhaustiveness Checking
### With Never
```typescript
enum Status {
Active,
Pending,
Deleted
}
function assertNever(x: never): never {
throw new Error("Unexpected value: " + x);
}
function processStatus(status: Status): string {
switch (status) {
case Status.Active:
return "Active";
case Status.Pending:
return "Pending";
case Status.Deleted:
return "Deleted";
default:
return assertNever(status);
}
}
```
## Ambient Enums
Declaration without implementation:
```typescript
declare enum Status {
Active,
Pending
}
// Used in .d.ts files
```
## Summary
- Enums create named constants
- Numeric enums auto-increment from 0
- String enums must be initialized
- Use `const enum` for better performance
- Reverse mapping: `Color[1]` gets key from value
- Enums are useful for status codes and choices
- Use exhaustiveness checking with `never`
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →