How to Check if an Enum Contains a Value in TypeScript

Suppose you’re building an admin panel for a web app where users can have one of several roles, such as admin, editor, or viewer.

You receive the user role from a backend API as a string, and you want to check whether this string is a valid role according to your enum before using it in your app.

For that, we need to check the backend API name with the enum’s value in TypeScript. In this tutorial, I will explain how to check if an enum contains a value in TypeScript.

Understanding Enums in TypeScript

Enums in TypeScript define a set of named constants. They can be numeric or string-based and provide a convenient way to handle a collection of related values.

Enums make the code more readable and maintainable by allowing you to use descriptive names instead of hard-coded values.

Checking if an Enum contains a value in TypeScript is a common task developers often encounter when working with enums, especially in large applications.

I faced this issue while working on a project for a client in New York, where we needed to validate user roles dynamically. Let’s dive into the details and explore different methods to achieve this.

Numeric Enums in TypeScript

Numeric enums are the default in TypeScript. They assign numeric values to each member starting from 0.

Imagine you’re managing order processing in an e-commerce app. You define a numeric enum for different order statuses.

enum OrderStatus {
  Pending,    // 0
  Shipped,    // 1
  Delivered,  // 2
  Cancelled   // 3
}

Now, you’re getting a number (e.g., from a database or user input) and need to check if it’s a valid OrderStatus before using it.

String Enums in TypeScript

String enums allow you to assign string values to each member, making the code more readable.

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

Why Check if an Enum Contains a Value in TypeScript?

When working with enums, you might need to validate if a given value is part of the enum. This is especially useful in scenarios such as:

  • Validating user input
  • Ensuring data integrity
  • Handling dynamic data from external sources

Methods to Check if an Enum Contains a Value

Now, let’s understand the different methods used to check whether an Enum contains a value in TypeScript.

1. Using Object.values() + includes

The Object.values() can be used for string enums to get an array of enum values and then check if the value exists.

You want to check if a string value (like “ACTIVE”) exists in a TypeScript enum, so when you say Status.Active, it gives you ‘ACTIVE‘.

Object.values(Status) gets all the values from the Status enum, such as [‘ACTIVE’, ‘INACTIVE’, ‘SUSPENDED’].

The .includes(value as Status) checks if the given string exists in that list. If it does, the function returns true and logs that it’s a valid status; otherwise, it returns false and logs that it’s invalid.

enum Status {
    Active = 'ACTIVE',
    Inactive = 'INACTIVE',
    Suspended = 'SUSPENDED',
  }
  
  function isValidStatus(value: string): value is Status {
    const isValid = Object.values(Status).includes(value as Status);
    console.log(`${value} is ${isValid ? 'a valid' : 'an invalid'} status.`);
    return isValid;
  }
  
  // Call the function
  isValidStatus('ACTIVE');
  isValidStatus('DEACTIVATED');

You can check the output of the above code below.

Enum Contains a Value in TypeScript

2. Using Object.keys() + enum[enumKey] === value

Below, I have explained how you can use Object.keys() + enum[enumKey] === value to check if a string exists in a string enum.

Using Object.keys(Status) retrieves the enum keys as an array of strings (e.g., [‘Active’, ‘Inactive’, ‘Suspended’]). Then, Status[key as keyof typeof Status] accesses the corresponding enum values (e.g., ‘ACTIVE’, ‘INACTIVE’).

The .some() method iterates through the keys and checks if the value matches the input string. It returns true if a match is found, indicating the input is a valid enum value.

enum Status {
    Active = 'ACTIVE',
    Inactive = 'INACTIVE',
    Suspended = 'SUSPENDED',
  }
  
  function isValidStatus(value: string): value is Status {
    const keys = Object.keys(Status); // ['Active', 'Inactive', 'Suspended']
    
    const isValid = keys.some((key) => {
      return Status[key as keyof typeof Status] === value;
    });
  
    console.log(`${value} is ${isValid ? 'a valid' : 'an invalid'} status.`);
    return isValid;
  }
  
  // Example usage
  isValidStatus('ACTIVE');       
  isValidStatus('DEACTIVATED');

Below you can check the output of the above code.

TypeScript to check the Enum

3. Using Reverse Lookup

In TypeScript, reverse lookup can be used to check if a numeric enum contains a value. TypeScript allows reverse mapping for numeric enums, meaning that you can use the numeric value to look up the corresponding key.

For string enums, reverse lookup does not apply because there’s no automatic key-value mapping like with numeric enums.

In TypeScript, reverse lookup is available for numeric enums, meaning you can use the numeric value to check if it exists in the enum. For example, using value in OrderStatus checks if a numeric value is a valid enum value.

The code defines a numeric enum OrderStatus with values for different order statuses. The isValidOrderStatus function uses the in operator to check if a given number exists as a valid key in the enum.

If the number matches one of the enum values (like 1 for Shipped), it returns true; otherwise, it returns false.

For example, isValidOrderStatus(1) returns true because 1 corresponds to Shipped, while isValidOrderStatus(4) returns false because 4 is not a valid enum value.

enum OrderStatus {
    Pending = 0,
    Shipped = 1,
    Delivered = 2,
    Cancelled = 3,
  }
  
  function isValidOrderStatus(value: number): boolean {
    // Reverse lookup
    return value in OrderStatus;
  }
  
  // Example usage
  console.log(isValidOrderStatus(1)); // Logs: true (Shipped)
  console.log(isValidOrderStatus(4)); // Logs: false (not valid)

Below you can check the output of the above code.

Using Reverse Lookup Check Enum Exist

4. Using Type Guard with Enums Example

Type guards in TypeScript help you narrow down the type of a value inside a specific scope.

When using enums, you can leverage type guards to ensure the value you’re working with is a valid enum value before performing operations on it. This makes the code safer and more predictable.

The isValidOrderStatus function is a type guard that checks if a value is a valid member of the OrderStatus enum using Object.values(…).includes(…).

It returns a type predicate, allowing TypeScript to treat the value as OrderStatus within a conditional block.

The printOrderStatus function uses this check to either print the corresponding enum label (e.g., “Shipped”) or log “Invalid order status” if the value is not part of the enum.

enum OrderStatus {
    Pending = 0,
    Shipped = 1,
    Delivered = 2,
    Cancelled = 3,
  }
  
  // Type guard to check if a value is a valid OrderStatus
  function isValidOrderStatus(value: any): value is OrderStatus {
    return Object.values(OrderStatus).includes(value);
  }
  
  function printOrderStatus(status: any) {
    if (isValidOrderStatus(status)) {
      console.log(`The order status is: ${OrderStatus[status]}`);
    } else {
      console.log('Invalid order status');
    }
  }
  
  // Example usage
  printOrderStatus(1); // Logs: The order status is: Shipped
  printOrderStatus(4); // Logs: Invalid order status

Below you can check the output of the above code.

Using Type Guard with TypeScript Enums Example

Real-World Example: User Role Validation

Let’s consider a real-world example where we need to validate user roles in a web application for a client in San Francisco.

The roles are defined in a string enum, and we need to ensure that the roles provided by users are valid.

Defining the Enum

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

Validation Function

We will create a function validateUserRole that takes a role as input and checks if it is a valid role.

function validateUserRole(role: string): boolean {
    return Object.values(UserRole).includes(role);
}

Usage in Application

We can use the validateUserRole function to validate user roles in different parts of the application, such as user registration or role assignment.

const userRole = "EDITOR";

if (validateUserRole(userRole)) {
    console.log(`${userRole} is a valid role.`);
} else {
    console.log(`${userRole} is not a valid role.`);
}

Handling Invalid Roles

If an invalid role is provided, we can handle it gracefully by providing feedback to the user or logging an error.

const userRole = "GUEST";

if (validateUserRole(userRole)) {
    console.log(`${userRole} is a valid role.`);
} else {
    console.error(`${userRole} is not a valid role.`);
    // Handle the invalid role case
}

Full TypeScript Code Example:

// Defining the Enum
enum UserRole {
    Admin = "ADMIN",
    Editor = "EDITOR",
    Viewer = "VIEWER"
  }
  
  // Validation Function
  function validateUserRole(role: string): role is UserRole {
    return Object.values(UserRole).includes(role as UserRole);
  }
  
  // Usage in Application - Valid Role
  const userRole1 = "EDITOR";
  
  if (validateUserRole(userRole1)) {
    console.log(`${userRole1} is a valid role.`);
  } else {
    console.error(`${userRole1} is not a valid role.`);
    // Handle invalid role here
  }
  
  // Usage in Application - Invalid Role
  const userRole2 = "GUEST";
  
  if (validateUserRole(userRole2)) {
    console.log(`${userRole2} is a valid role.`);
  } else {
    console.error(`${userRole2} is not a valid role.`);
    // Handle invalid role here
  }
  

You can check the output of the above code below.

User Role Validation Using Enum TypeScript

Advanced Techniques in TypeScript

1. Custom Utility Function with Generics

We can create a utility function that accepts any enum and value to make the validation reusable.

function isEnumValue<T>(enumObj: T, value: any): boolean {
    return Object.values(enumObj).includes(value);
}

// Usage
const userRole = "ADMIN";
console.log(isEnumValue(UserRole, userRole)); // true

2. TypeScript Generics

Using TypeScript generics, we can create a more flexible utility function.

enum UserRole {
  ADMIN = "ADMIN",
  USER = "USER",
  GUEST = "GUEST"
}

function isEnumValue<T extends Record<string, string | number>>(
  enumObj: T,
  value: any
): value is T[keyof T] {
  return Object.values(enumObj).includes(value);
}

// Usage
const userRole = "ADMIN";
console.log(isEnumValue(UserRole, userRole)); // true
Generic TypeScript

Conclusion

In this tutorial, we explored various methods to check if a value is part of an enum in TypeScript. We covered numeric and string enums and demonstrated practical examples for user role validation. By using these techniques, you can ensure data integrity and handle dynamic data more effectively in your TypeScript applications.

You may like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.