Retrieving TypeScript Enum Values: Deep Understanding and Implementation Methods

Dec 08, 2025 · Programming · 16 views · 7.8

Keywords: TypeScript | Enum | JavaScript Object | Bidirectional Mapping | Object.keys

Abstract: This article explores the implementation mechanism of TypeScript enums in JavaScript, explaining why direct use of Object.keys() returns mixed results and providing multiple methods to obtain pure enum values. By analyzing the compiled structure of enums, it details the bidirectional mapping characteristics of numeric and string keys, and presents complete code examples and performance comparisons for solutions using Object.keys().filter(), Object.values(), and other approaches.

Underlying Implementation Mechanism of TypeScript Enums

When TypeScript enums are compiled to JavaScript, they generate a special bidirectional mapping object. For the Color enum example:

export enum Color {
    Red,
    Green,
    Blue,
}

The compiled JavaScript object structure is as follows:

{
    '0': 'Red',
    '1': 'Green',
    '2': 'Blue',
    Red: 0,
    Green: 1,
    Blue: 2
}

This design allows accessing enum names via numeric indices and accessing corresponding numeric values via enum names:

console.log(Color[0]); // "Red"
console.log(Color["Red"]); // 0

Solutions for Obtaining Pure Enum Values

Since enum objects contain both numeric and string keys, directly using Object.keys() returns all keys:

const allKeys = Object.keys(Color);
// Result: ['0', '1', '2', 'Red', 'Green', 'Blue']

Method 1: Using filter to Exclude Numeric Keys

The most common approach is to filter out numeric keys, retaining only string keys:

const enumValues = Object.keys(Color).filter((key) => {
    return isNaN(Number(key));
});
// Result: ['Red', 'Green', 'Blue']

This method utilizes the isNaN() function to determine whether a key is numeric, based on the principle that numeric strings convert to numbers (not NaN), while enum names convert to NaN.

Method 2: Using Object.values() (TypeScript 3.1+)

For newer TypeScript versions, Object.values() combined with type assertions can be used:

const values = Object.values(Color).filter(
    (value): value is string => typeof value === 'string'
);
// Result: ['Red', 'Green', 'Blue']

This approach is more concise but requires attention to TypeScript version compatibility.

Method 3: Using for...in Loop

Manually iterate through the enum object, selecting string keys:

const enumValues: string[] = [];
for (const key in Color) {
    if (isNaN(Number(key))) {
        enumValues.push(key);
    }
}
// Result: ['Red', 'Green', 'Blue']

Performance Analysis and Best Practices

Regarding performance, the three methods have their own advantages and disadvantages:

  1. Filter Method: Concise code, good readability, suitable for most scenarios
  2. Object.values() Method: Modern JavaScript feature, better performance
  3. for...in Loop: Most flexible, capable of handling more complex filtering logic

It is recommended to choose the appropriate method based on TypeScript version and performance requirements in actual projects. For large enums, consider caching results to avoid repeated calculations.

Extended Application Scenarios

Methods for obtaining enum values can be applied to various scenarios:

  1. Dynamic Form Generation: Automatically generate dropdown options based on enum values
  2. Data Validation: Validate whether input values are valid enum values
  3. Internationalization: Retrieve corresponding localized text based on enum values

Example: Dynamically generating select box options

function createSelectOptions(enumObj: any): string {
    const values = Object.keys(enumObj).filter(key => isNaN(Number(key)));
    return values.map(value => `<option value="${value}">${value}</option>`).join('');
}

Conclusion

Understanding the underlying implementation of TypeScript enums is key to correctly retrieving enum values. By analyzing the compiled JavaScript object structure, we can choose appropriate methods to filter numeric keys and obtain arrays of pure enum names. In practical development, select the most suitable implementation based on project requirements and TypeScript version.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.