;

TypeScript Enums


Enums in TypeScript provide a way to define a set of named constants, making code easier to read and understand. They’re especially useful when you need a collection of related values that won’t change, such as days of the week or status codes. This tutorial covers everything you need to know about TypeScript enums, from basic syntax to advanced usage and real-world applications.

Introduction to TypeScript Enums

Enums (short for “enumerations”) in TypeScript provide a way to define named constants, creating a type-safe way to work with a fixed set of values. Enums can represent both numeric and string values, giving you flexibility in how they are used. This guide will walk you through everything from the basics to advanced applications, making it easy to integrate enums into your TypeScript projects.

What is an Enum in TypeScript?

An enum is a way to create a collection of related values, each with its own name. Enums in TypeScript can be of two types: numeric and string. They allow you to use friendly names to refer to fixed values, making your code easier to read and reducing errors caused by using “magic numbers” or strings.

enum Status {
  Pending,
  InProgress,
  Completed
}

In this example:

  • Status is an enum with three possible values: Pending, InProgress, and Completed.
  • Each value represents a unique constant, making it easier to use and understand in your code.

Declaring Enums

Enums in TypeScript can be declared in two ways: as numeric enums and as string enums.

Numeric Enums

Numeric enums are the default in TypeScript. When you declare a numeric enum, each member is assigned a numeric value starting from 0 by default, and each subsequent member’s value is incremented by 1.

enum Direction {
  Up,      // 0
  Down,    // 1
  Left,    // 2
  Right    // 3
}

console.log(Direction.Up);    // Output: 0
console.log(Direction.Right); // Output: 3

In this example:

  • Direction is a numeric enum where Up is assigned 0, Down is assigned 1, and so on.
  • TypeScript automatically increments values, making it easy to create ordered sets.

Custom Numeric Values

You can assign custom values to enum members, and TypeScript will continue incrementing from the specified value.

enum Role {
  Admin = 1,
  User = 5,
  Guest    // 6 (incremented automatically)
}

console.log(Role.Admin); // Output: 1
console.log(Role.Guest); // Output: 6

Here:

  • Role has custom values, where Admin starts at 1, and User is 5.
  • Guest is automatically assigned 6, continuing from User.

String Enums

String enums allow you to assign meaningful names as values to the enum members instead of numeric values. This is useful when the values themselves convey information.

enum Status {
  Pending = "PENDING",
  InProgress = "IN_PROGRESS",
  Completed = "COMPLETED"
}

console.log(Status.Pending); // Output: PENDING

In this example:

  • Status is a string enum with each member assigned a specific string value.
  • String enums improve readability and avoid accidental assignments, as you must use the exact string.

Accessing Enum Values and Keys

You can access enum values and keys in TypeScript using dot notation. TypeScript enums are bi-directional for numeric enums, meaning you can get the name of an enum by its value and vice versa.

Accessing Enum Values by Key

enum Days {
  Monday,
  Tuesday,
  Wednesday
}

console.log(Days.Monday); // Output: 0
console.log(Days.Tuesday); // Output: 1

Accessing Enum Names by Value (Numeric Enums Only)

With numeric enums, you can use the value to get the key.

console.log(Days[0]); // Output: Monday
console.log(Days[1]); // Output: Tuesday

String enums, however, are one-directional, meaning you can only access the value by the key, not the other way around.

Computed and Constant Enums

TypeScript allows for two types of enums based on initialization behavior: constant enums and computed enums.

Constant Enums

Constant enums are inlined at compile time and cannot have computed values. They are prefixed with const and are used to optimize performance.

const enum Colors {
  Red,
  Green,
  Blue
}

let myColor = Colors.Green; // Optimized to just `1` in compiled JS

In this example:

  • Colors is a constant enum that gets inlined, improving performance by omitting unused enum definitions in the compiled JavaScript code.

Computed Enums

Computed enums allow for values to be derived from expressions. They are not prefixed with const and can include more complex logic.

enum Shapes {
  Circle = Math.PI,
  Square = 4
}

console.log(Shapes.Circle); // Output: 3.141592653589793

Here:

  • Shapes is a computed enum where the value of Circle is calculated using Math.PI.
  • Computed values offer flexibility but prevent inlining optimizations.

Using Enums in Functions and Logic

Enums are useful in controlling flow and adding type safety to function parameters and return values. You can use enums in conditions, loops, and switch statements.

Example: Enums in Function Parameters

Enums add type safety when used as function parameters, ensuring only valid values are passed.

enum TaskStatus {
  NotStarted,
  InProgress,
  Done
}

function updateTaskStatus(status: TaskStatus): void {
  if (status === TaskStatus.Done) {
    console.log("Task is complete!");
  } else {
    console.log("Task is not complete.");
  }
}

updateTaskStatus(TaskStatus.Done);      // Output: Task is complete!
updateTaskStatus(TaskStatus.InProgress); // Output: Task is not complete.

Example: Switch Statements with Enums

Switch statements pair well with enums, making it easy to execute different logic based on enum values.

enum Level {
  Easy,
  Medium,
  Hard
}

function getGameLevel(level: Level): void {
  switch (level) {
    case Level.Easy:
      console.log("You selected Easy level.");
      break;
    case Level.Medium:
      console.log("You selected Medium level.");
      break;
    case Level.Hard:
      console.log("You selected Hard level.");
      break;
  }
}

getGameLevel(Level.Medium); // Output: You selected Medium level.

In this example:

  • The getGameLevel function handles each Level value differently.
  • Enums make it clear which values are valid, ensuring all cases are handled properly.

Real-World Examples of Using Enums

Example 1: Defining User Roles

Enums are commonly used to manage user roles and access levels in applications.

enum UserRole {
  Admin = "ADMIN",
  Editor = "EDITOR",
  Viewer = "VIEWER"
}

function checkPermission(role: UserRole): void {
  if (role === UserRole.Admin) {
    console.log("Full access granted.");
  } else if (role === UserRole.Editor) {
    console.log("Editing access granted.");
  } else {
    console.log("Read-only access granted.");
  }
}

checkPermission(UserRole.Editor); // Output: Editing access granted.

Example 2: Configuring Application Themes

Enums can be used for configuration options, such as defining themes in an application.

enum Theme {
  Light = "light",
  Dark = "dark",
  System = "system"
}

function setTheme(theme: Theme): void {
  console.log(`Applying ${theme} theme`);
}

setTheme(Theme.Dark); // Output: Applying dark theme

In this example:

  • Theme is a string enum used to define valid theme options.
  • Enums make it easier to maintain consistent theme values across the application.

Key Takeaways

  1. Enums for Named Constants: Enums provide a way to define a set of named constants, improving code readability and reducing errors.
  2. Numeric vs. String Enums: TypeScript supports both numeric and string enums. Numeric enums are the default, but string enums are useful for readable values.
  3. Accessing Enum Values and Keys: Numeric enums allow reverse mapping, letting you access keys by their values. String enums do not support this feature.
  4. Constant vs. Computed Enums: Constant enums improve performance by being inlined, while computed enums allow for complex initialization.
  5. Real-World Use Cases: Enums are widely used in defining user roles, themes, statuses, and configuration options.

Summary

Enums in TypeScript are an effective way to represent a set of related constants. They improve code readability and type safety, making it easier to work with fixed values. This guide covered how to declare numeric and string enums, access enum values, use enums in functions, and apply them in real-world scenarios. With this understanding, you can confidently use enums to create structured, maintainable, and type-safe code in your TypeScript projects.