TypeScript Enums

Welcome to The Coding College! At The Coding College, we’re dedicated to making programming concepts simple and accessible. In this guide, we’ll dive into TypeScript Enums, a powerful feature for creating named constants with fixed values.

What Are Enums in TypeScript?

An enum in TypeScript is a way to define a set of named constants. It’s a useful construct when you want to represent a group of related values, such as days of the week, user roles, or status codes, in a type-safe and readable way.

Types of Enums in TypeScript

1. Numeric Enums

The default type of an enum is numeric, where values are assigned sequentially starting from 0.

Example:

enum Status {
    Active,     // 0
    Inactive,   // 1
    Pending,    // 2
}
console.log(Status.Active); // Output: 0
console.log(Status[1]); // Output: Inactive

Custom Starting Value:

You can set a custom starting value, and subsequent members will increment from that value.

enum HttpStatus {
    OK = 200,
    NotFound = 404,
    InternalServerError = 500,
}
console.log(HttpStatus.OK); // Output: 200

2. String Enums

String enums associate each member with a string value.

enum UserRole {
    Admin = "ADMIN",
    User = "USER",
    Guest = "GUEST",
}
console.log(UserRole.Admin); // Output: ADMIN

3. Heterogeneous Enums

Enums can mix string and numeric values, although it’s less common.

enum Mixed {
    Yes = "YES",
    No = 0,
}
console.log(Mixed.Yes); // Output: YES
console.log(Mixed.No);  // Output: 0

Why Use Enums?

1. Improved Readability

Enums provide meaningful names to constant values, making the code easier to understand.

// Without enums:
let status = 1; // What does 1 mean?

// With enums:
enum Status {
    Active = 1,
    Inactive = 2,
}
let status: Status = Status.Active; // Clear and readable

2. Type Safety

Enums ensure that only valid values can be assigned to a variable.

enum Direction {
    North,
    South,
    East,
    West,
}
let dir: Direction = Direction.North;
// dir = 5; // Error: Type '5' is not assignable to type 'Direction'

Enum Operations

1. Reverse Mapping (Numeric Enums Only)

Numeric enums support reverse mapping, allowing you to get the name of a value.

enum Colors {
    Red = 1,
    Green,
    Blue,
}
console.log(Colors[1]); // Output: Red

2. Accessing Enum Members

You can access enum members using dot notation.

enum Days {
    Monday,
    Tuesday,
    Wednesday,
}
console.log(Days.Tuesday); // Output: 1

Enum as a Type

Enums can also act as types, enforcing the use of specific values.

enum Transport {
    Car,
    Bike,
    Plane,
}

let travelMode: Transport = Transport.Car;
// travelMode = "Train"; // Error: Type '"Train"' is not assignable to type 'Transport'

Real-World Applications of Enums

1. Status Codes

Enums can represent HTTP status codes for better code clarity.

enum HttpStatus {
    OK = 200,
    BadRequest = 400,
    Unauthorized = 401,
}
function handleResponse(status: HttpStatus) {
    if (status === HttpStatus.OK) {
        console.log("Request successful!");
    }
}

2. User Roles

Enums are ideal for representing user roles in an application.

enum UserRole {
    Admin,
    Editor,
    Viewer,
}

function checkAccess(role: UserRole) {
    if (role === UserRole.Admin) {
        console.log("Access granted!");
    }
}

3. Application States

Enums can represent application states like loading, success, and error.

enum AppState {
    Loading,
    Success,
    Error,
}
let currentState: AppState = AppState.Loading;

Advanced Enum Features

1. Computed and Constant Members

Enums can include both constant and computed members.

enum Example {
    Constant = 5,
    Computed = "Value".length, // Computed member
}
console.log(Example.Computed); // Output: 5

2. Union Enums

Enums can be used as union types for more complex use cases.

enum ShapeType {
    Circle = "CIRCLE",
    Square = "SQUARE",
}

function drawShape(type: ShapeType) {
    if (type === ShapeType.Circle) {
        console.log("Drawing a circle.");
    }
}
drawShape(ShapeType.Circle);

Best Practices for Using Enums

  1. Use String Enums for Flexibility: String enums are often easier to debug as they provide descriptive values.
  2. Avoid Heterogeneous Enums: Mixing types can lead to confusion and bugs.
  3. Define Descriptive Names: Ensure enum names and values are self-explanatory.

Common Mistakes with Enums

1. Confusing Numeric Enum Values

Numeric enums may lead to confusion when reverse mapping is used inadvertently.

enum Direction {
    Up = 1,
    Down,
    Left,
    Right,
}
console.log(Direction[2]); // Output: Down (but might be unclear in some contexts)

2. Overusing Enums

For simple cases, consider using union types instead of enums.

// Instead of this:
enum YesNo {
    Yes,
    No,
}

// Use this:
type YesNo = "Yes" | "No";

Conclusion

Enums in TypeScript are a versatile tool for creating type-safe, readable, and maintainable code. Whether you’re working on user roles, status codes, or application states, enums can simplify your logic and reduce errors.

Leave a Comment