TypeScript Enum Duplicate Values

Recently, I was working on a TypeScript project where I needed to create an enum with duplicate values. It looks simple, but a little tricky to handle duplicate values in TypeScript. The issue is… There are specific behaviors you need to understand when working with enum duplicates.

In this tutorial, I will explain several approaches to handle duplicate values in TypeScript enums (including their pros and cons, and some best practices). So let’s dive in!

What Are TypeScript Enums and Why Duplicate Values Matter

TypeScript enums allow us to define a set of named constants. They make it easier to document intent or create a set of distinct cases.

Here’s a simple enum example:

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

But what happens when we need to have multiple enum members share the same value? This is where duplicate values come into play.

Check out How to Get Enum by Name in TypeScript

Now, let me show different methods to work with duplicate values in TypeScript.

Method 1: Using Basic Enum with Duplicate Values

TypeScript actually allows duplicate values in enums without any errors. Let’s see how this works:

enum USState {
  California = 1,
  Texas = 2,
  Florida = 3,
  NewYork = 3  // Duplicate value with Florida
}

console.log(USState.Florida);  // Outputs: 3
console.log(USState.NewYork);  // Also outputs: 3
console.log(USState[3]);       // Outputs: "NewYork" (not "Florida")

Notice that when we access the enum value by name, both Florida and NewYork return 3. However, when we try to get the name by value using USState[3], we only get “NewYork”. This is because with duplicate values, the last defined member “wins” when accessing by value.

Here is the exact output in the screenshot below:

typescript enum duplicate values

Check out Convert Enums to Strings in TypeScript

Method 2: Using Const Enums for Better Performance

If you’re concerned about runtime performance, const enums can be a good choice even with duplicate values:

const enum HttpStatus {
  OK = 200,
  Created = 201,
  Accepted = 202,
  SuccessfulResponse = 200  // Duplicate with OK
}

const status = HttpStatus.OK;
const alsoStatus = HttpStatus.SuccessfulResponse;

With const enums, TypeScript replaces enum references with their actual values during compilation. The compiled JavaScript would look like:

const status = 200;
const alsoStatus = 200;

This approach reduces runtime overhead but maintains the clarity of using meaningful names in your code.

Read TypeScript Switch with Enums

Method 3: Using Object Literals as Enum Alternatives

If enum duplicates cause issues in your project, consider using object literals as an alternative:

const USTimeZone = {
  Eastern: "ET",
  Central: "CT",
  Mountain: "MT",
  Pacific: "PT",
  Alaska: "AT",
  Hawaii: "HT",
  EasternAlternate: "ET"  // Duplicate value with Eastern
} as const;

type USTimeZoneType = typeof USTimeZone[keyof typeof USTimeZone];

This approach gives you more control over how duplicates are handled, and the as const assertion ensures type safety similar to enums.

Method 4: Using String Enums with Duplicates

String enums can also have duplicate values:

enum USRegion {
  Northeast = "cold-weather",
  Midwest = "four-seasons",
  South = "warm-weather",
  Southwest = "dry-heat",
  West = "mild-climate",
  Northwest = "rainy",
  SouthernCalifornia = "mild-climate"  // Duplicate with West
}

console.log(USRegion.West);  // Outputs: "mild-climate"
console.log(USRegion.SouthernCalifornia);  // Also outputs: "mild-climate"

String enums don’t support reverse mapping (you can’t access USRegion["mild-climate"]), which actually avoids some of the confusion that numeric enums with duplicates can cause.

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

Method 5: Using Union Types Instead of Enums

For complete type safety with duplicate values, consider union types:

type PaymentStatus = 
  | { status: "pending"; code: 100 }
  | { status: "processing"; code: 200 }
  | { status: "completed"; code: 300 }
  | { status: "successful"; code: 300 };  // Duplicate code with completed

function handlePayment(payment: PaymentStatus) {
  if (payment.code === 300) {
    // This handles both "completed" and "successful" statuses
    console.log("Payment finalized:", payment.status);
  }
}

This approach gives you more flexibility and avoids the potential confusion of enum reverse lookups with duplicates.

Here is the complete code:

type PaymentStatus = 
  | { status: "pending"; code: 100 }
  | { status: "processing"; code: 200 }
  | { status: "completed"; code: 300 }
  | { status: "successful"; code: 300 };  // Duplicate code with completed

function handlePayment(payment: PaymentStatus) {
  if (payment.code === 300) {
    // This handles both "completed" and "successful" statuses
    console.log("Payment finalized:", payment.status);
  } else {
    console.log("Payment in progress:", payment.status);
  }
}

// Example usage:
const payment1: PaymentStatus = { status: "completed", code: 300 };
const payment2: PaymentStatus = { status: "successful", code: 300 };
const payment3: PaymentStatus = { status: "processing", code: 200 };

handlePayment(payment1);  // Output: Payment finalized: completed
handlePayment(payment2);  // Output: Payment finalized: successful
handlePayment(payment3);  // Output: Payment in progress: processing

You can see the exact output in the screenshot below:

enum duplicate values typescript

Check out How to Use TypeScript Enum Reverse Mapping

Best Practices for Working with Enum Duplicates

After working with TypeScript enums for years, I’ve developed some best practices:

  1. Document duplicate values – Always add comments explaining why duplicates exist
  2. Consider using string enums – They’re more explicit and avoid reverse mapping issues
  3. Use const assertions with object literals for more control
  4. Be cautious with reverse lookups (MyEnum[value]) when duplicates exist
  5. Write unit tests specifically for code that uses enums with duplicates

When to Avoid Enum Duplicates

While duplicates can be useful, there are scenarios where they should be avoided:

  • When you need reliable bidirectional mapping (value to name and name to value)
  • In public APIs where consumers might expect unique values
  • When the duplicate might indicate a design issue in your code

For example, if you’re modeling U.S. states, having duplicate values might indicate a conceptual problem since each state should be unique.

I hope you found this article helpful. You must learn everything now about TypeScript enums with duplicate values. By following the methods and best practices outlined here, you can use enum duplicates effectively in your projects.

You may like the following tutorials:

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