Check If a Value Is in an Enum in TypeScript (5 Reliable Methods)

In my TypeScript journey spanning over 6 years, I’ve frequently encountered situations where I needed to validate if a particular string or value exists within an enum. This is especially common when working with user inputs or API responses.

TypeScript enums provide a way to define a set of named constants, but checking if a value belongs to an enum isn’t always straightforward.

In this article, I’ll share five practical methods to check if a value exists in a TypeScript enum, complete with real-world examples and best practices I’ve learned along the way.

What are TypeScript Enums?

Before diving into the validation methods, let’s quickly review what enums are in TypeScript.

Enums allow us to define a set of named constants, making our code more readable and maintainable. They come in three flavors: numeric enums, string enums, and heterogeneous enums.

Here’s a simple example of a string enum representing US states:

enum USState {
  CALIFORNIA = "CA",
  TEXAS = "TX",
  NEW_YORK = "NY",
  FLORIDA = "FL"
}

Now, let’s explore how to check if a value exists in this TypeScript enum.

Method 1: Using Object.values() for Value Validation

One of the most straightforward ways to check if a value exists in an enum is using Object.values(). However, there’s a type compatibility issue we need to address:

enum USState {
  CALIFORNIA = "CA",
  TEXAS = "TX",
  NEW_YORK = "NY",
  FLORIDA = "FL"
}

function isUSStateValue(value: string): boolean {
  // Type assertion is necessary because Object.values(USState) returns USState[]
  // and includes() expects a parameter of type USState, not string
  return Object.values(USState).includes(value as any);
}

// Usage
console.log(isUSStateValue("CA")); // true
console.log(isUSStateValue("WA")); // false

Notice the as any type assertion. Without it, TypeScript would give an error: “Argument of type ‘string’ is not assignable to parameter of type ‘USState'”. This happens because Object.values(USState) returns an array of USState type values, not strings.

This method works well when you need to check if a specific value (like “CA”) is part of your enum. It’s particularly useful for string enums where you’re validating against enum values rather than keys.

You can see the exact output in the screenshot below:

typescript check if value is in enum

Check out Convert TypeScript Enums to Arrays

Method 2: Using Type Guards with Key Checks

Another approach is to check if a string exists as a key in the TypeScript enum:

enum USState {
    CALIFORNIA = "CA",
    TEXAS = "TX",
    NEW_YORK = "NY",
    FLORIDA = "FL"
  }
  
  function isUSStateKey(key: string): key is keyof typeof USState {
    return key in USState;
  }
  
  // Usage
  console.log(isUSStateKey("CALIFORNIA")); // true
  console.log(isUSStateKey("WASHINGTON")); // false

This method is perfect when you’re working with dynamic keys and need to ensure type safety. The type guard key is keyof typeof USState helps TypeScript understand that the key exists in the enum if the function returns true.

I executed the above code using VS Code, and you can see the exact output in the screenshot below:

typescript check if value belongs to enum

Check out Check If a String Is in an Enum in TypeScript

Method 3: Using Reverse Mapping for Numeric Enums

For numeric enums, TypeScript generates reverse mappings automatically, which we can leverage:

enum USRegion {
  WEST = 1,
  SOUTH = 2,
  NORTHEAST = 3,
  MIDWEST = 4
}

function isValidRegion(value: number): boolean {
  return USRegion[value] !== undefined;
}

// Usage
console.log(isValidRegion(1)); // true (WEST)
console.log(isValidRegion(5)); // false (doesn't exist)

This technique works specifically for numeric enums due to TypeScript’s reverse mapping feature, but it won’t work for string enums.

Here is the exact output of the above TypeScript code:

how to check if an enum contains a value typescript

Method 4: Using a Generic Type-Safe Function

For a more reusable approach, we can create a generic function that works with any enum:

function isEnumValue<T extends Record<string, string | number>>(
  enumObject: T,
  value: string | number
): boolean {
  return Object.values(enumObject).includes(value);
}

// Usage with different enums
console.log(isEnumValue(USState, "CA")); // true
console.log(isEnumValue(USRegion, 2)); // true (SOUTH)

This generic function provides type safety and works with both string and numeric enums. It’s my go-to solution when building libraries or utilities that require validation against various enum types.

Check out TypeScript Enum Naming Conventions

Method 5: Creating a Utility Type for Exhaustive Validation

Sometimes we need to validate at compile-time. Here’s a utility type I often use:

type ValueOf<T> = T[keyof T];
type USStateValue = ValueOf<typeof USState>;

function processStateValue(value: unknown): void {
  if (isUSStateValue(value)) {
    // TypeScript knows value is a valid USState value here
    console.log(`Processing state: ${value}`);
  } else {
    console.log("Invalid state value");
  }
}

function isUSStateValue(value: unknown): value is USStateValue {
  return typeof value === 'string' && Object.values(USState).includes(value as any);
}

This approach provides the strongest type safety, ensuring you’re working with valid enum values throughout your codebase.

Check out Convert String to Enum in TypeScript

Real-World Example: Form Validation for US States

Let’s see how these methods apply to a real-world scenario. Imagine we’re validating a user form with a state field:

interface UserAddress {
  street: string;
  city: string;
  state: string;
  zipCode: string;
}

function validateAddress(address: UserAddress): { isValid: boolean, errors: string[] } {
  const errors: string[] = [];

  // Validate state using our enum check
  if (!isUSStateValue(address.state)) {
    errors.push(`Invalid state code: ${address.state}. Please use a valid US state code (e.g., CA, TX).`);
  }

  // Additional validation logic for other fields
  // ...

  return {
    isValid: errors.length === 0,
    errors
  };
}

// Test with valid data
const validAddress: UserAddress = {
  street: "123 Main St",
  city: "Los Angeles",
  state: "CA",
  zipCode: "90001"
};

// Test with invalid data
const invalidAddress: UserAddress = {
  street: "456 Elm St",
  city: "Seattle",
  state: "WA", // Not in our enum
  zipCode: "98101"
};

console.log(validateAddress(validAddress));
console.log(validateAddress(invalidAddress));

This pattern ensures that only valid state codes, as defined in our enum, are accepted, thereby improving data integrity and the user experience.

Check out How to Iterate Over Enums in TypeScript?

Handle Case Sensitivity

One common issue when validating enum values is case sensitivity. If you need case-insensitive validation, modify your check like this:

function isUSStateValueCaseInsensitive(value: string): boolean {
  return Object.values(USState)
    .some(state => typeof state === 'string' && 
          state.toLowerCase() === value.toLowerCase());
}

// Usage
console.log(isUSStateValueCaseInsensitive("ca")); // true (matches "CA")

This approach is particularly useful when validating user input where case consistency isn’t guaranteed.

Performance Considerations

For performance-critical applications, consider these optimizations:

  1. Cache results: If you’re checking the same values repeatedly, cache the results.
  2. Set-based lookups: Convert enum values to a Set for O(1) lookups.
// Create a set of enum values for faster lookups
const usStateSet = new Set(Object.values(USState));

function isUSStateValueFast(value: string): boolean {
  return usStateSet.has(value);
}

This optimization is especially valuable in loops or when processing large datasets.

When to Use Each Method

Here’s a quick reference for choosing the right method:

MethodBest ForLimitations
Object.values()Simple value validationNo type safety
Key checkingWorking with enum keysDoesn’t work for values
Reverse mappingNumeric enumsDoesn’t work for string enums
Generic functionLibrary codeRequires type annotations
Utility typesType-safe codeMore complex setup

I hope you found this guide helpful for checking if values exist in TypeScript enums. These patterns have saved me countless hours of debugging and improved the reliability of my TypeScript applications.

If you have any questions or other approaches you’ve found useful, please share them in the comments below!

You may also like:

Power Apps functions free pdf

30 Power Apps Functions

This free guide walks you through the 30 most-used Power Apps functions with real business examples, exact syntax, and results you can see.

Download User registration canvas app

DOWNLOAD USER REGISTRATION POWER APPS CANVAS APP

Download a fully functional Power Apps Canvas App (with Power Automate): User Registration App