Question
In TypeScript, how can I iterate over an enum and get the name of each enum member?
For example:
enum MyEnum {
Entry1,
Entry2
}
for (const entry in MyEnum) {
// How can I use the enum member name here,
// such as "Entry1" or "Entry2"?
}
I want to loop through the enum object and access each declared symbol name.
Short Answer
By the end of this page, you will understand how TypeScript enums are represented at runtime, why iterating over them can produce unexpected results, and how to safely get enum member names. You will also learn the difference between numeric and string enums, common iteration patterns, and when to use alternatives like Object.keys() or Object.values().
Concept
TypeScript enums are a way to define a fixed set of named constants.
For example:
enum MyEnum {
Entry1,
Entry2
}
This creates named members:
MyEnum.Entry1MyEnum.Entry2
But an important detail is that enums also exist as JavaScript objects at runtime. That means you can loop over them with normal object tools like:
for...inObject.keys()Object.values()Object.entries()
Why iteration can be confusing
Numeric enums in TypeScript create reverse mappings.
This enum:
enum MyEnum {
Entry1,
Entry2
}
is roughly compiled into something like:
{
: ,
: ,
: ,
:
}
Mental Model
Think of a numeric enum like a bilingual dictionary.
It lets you look up in both directions:
- name -> number
- number -> name
So for:
enum MyEnum {
Entry1,
Entry2
}
TypeScript stores both:
Entry1 -> 00 -> Entry1Entry2 -> 11 -> Entry2
When you loop through the enum object, you are opening the whole dictionary, not just the list of original names.
If you only want the declared member names, you need to filter out the numeric side.
Syntax and Examples
Basic enum
enum MyEnum {
Entry1,
Entry2
}
Using for...in
for (const key in MyEnum) {
console.log(key);
}
For a numeric enum, this prints:
0
1
Entry1
Entry2
That happens because numeric enums include reverse mapping.
Get only the enum member names
A common approach is to filter out numeric keys:
enum MyEnum {
Entry1,
Entry2
}
for (const key in MyEnum) {
if (isNaN(Number(key))) {
console.(key);
}
}
Step by Step Execution
Consider this code:
enum MyEnum {
Entry1,
Entry2
}
const keys = Object.keys(MyEnum);
const names = keys.filter(key => isNaN(Number(key)));
console.log(keys);
console.log(names);
Step 1: Define the enum
enum MyEnum {
Entry1,
Entry2
}
At runtime, this behaves roughly like:
{
0: "Entry1",
1: "Entry2",
Entry1: 0,
Entry2: 1
}
Step 2: Read all object keys
const keys = .();
Real World Use Cases
Building dropdown menus
You may have an enum for status values:
enum Status {
Draft,
Published,
Archived
}
You can extract names to generate select options.
Validating incoming values
If an API or form sends a value that must match an enum, you can compare against enum keys or values.
Rendering labels in admin panels
Enums are often used for roles, states, categories, or modes. Iterating the enum lets you render all available choices.
Configuration and feature flags
A project may define a small set of supported environments or modes using an enum, then loop through them when building config tools.
Logging and debugging
When debugging state transitions, enum names are easier to read than raw numbers.
Real Codebase Usage
In real codebases, developers often avoid raw for...in loops on enums unless they specifically understand the enum shape.
Common patterns include:
Using Object.keys() with filtering
const enumNames = Object.keys(MyEnum).filter(key => isNaN(Number(key)));
This is common for numeric enums.
Using string enums for cleaner runtime behavior
enum Role {
Admin = "ADMIN",
User = "USER"
}
String enums avoid reverse mapping, which makes iteration easier.
Creating helper utilities
Projects often define one helper and reuse it:
function enumKeys(enumObj: object): string[] {
return Object.(enumObj).( ((key)));
}
Common Mistakes
Mistake 1: Assuming for...in gives only enum names
Broken expectation:
enum MyEnum {
Entry1,
Entry2
}
for (const key in MyEnum) {
console.log(key);
}
Many beginners expect:
Entry1
Entry2
But they actually get numeric keys too.
Fix
for (const key in MyEnum) {
if (isNaN(Number(key))) {
console.log(key);
}
}
Mistake 2: Forgetting the difference between numeric and string enums
Numeric enum:
enum A {
One,
Two
}
String enum:
Comparisons
| Approach | Works with numeric enums | Works with string enums | Returns | Notes |
|---|---|---|---|---|
for...in | Yes | Yes | Keys | Numeric enums include reverse-mapping keys |
Object.keys() | Yes | Yes | Keys | Usually the clearest choice |
Object.values() | Yes | Yes | Values | Numeric enums may include both names and numbers |
Object.entries() | Yes | Yes | Key-value pairs | Useful when building label/value lists |
Cheat Sheet
Get enum names from a numeric enum
enum MyEnum {
Entry1,
Entry2
}
const names = Object.keys(MyEnum).filter(key => isNaN(Number(key)));
Get enum names with for...in
for (const key in MyEnum) {
if (isNaN(Number(key))) {
console.log(key);
}
}
Numeric enums
enum A {
One,
Two
}
Runtime shape includes both:
A.One === 0A[0] === "One"
String enums
FAQ
Why does iterating a TypeScript enum return numbers and names?
Because numeric enums create reverse mappings at runtime. The enum object stores both name -> value and value -> name.
How do I get only enum member names in TypeScript?
Use:
Object.keys(MyEnum).filter(key => isNaN(Number(key)))
Do string enums have reverse mapping?
No. String enums do not create reverse mappings, so their keys are simpler to iterate.
Should I use for...in or Object.keys() for enums?
Object.keys() is usually clearer because it returns an array you can easily filter and map.
Can I use Object.values() on enums?
Yes, but with numeric enums it can include both names and numeric values, so be careful.
Are TypeScript enums arrays?
No. Enums are objects at runtime.
What is the easiest enum type to iterate?
String enums are usually easier because they do not include reverse mapping.
Mini Project
Description
Create a small TypeScript utility that turns an enum into a list of options for a dropdown menu. This demonstrates how to safely extract enum member names and pair them with values, which is a common task in forms and admin dashboards.
Goal
Build a function that converts a TypeScript enum into an array of { label, value } objects using only the real enum member names.
Requirements
- Define one numeric enum and one string enum.
- Write a reusable function to extract only enum member names.
- Create a second function that converts an enum into dropdown-style option objects.
- Print the results for both enums.
- Make sure numeric enum reverse-mapping keys are excluded.
Keep learning
Related questions
Angular formGroup Error Explained: Fixing 'Can't bind to formGroup' in Reactive Forms
Learn why Angular shows 'Can't bind to formGroup' and how to fix it by importing ReactiveFormsModule correctly.
Fix "Element implicitly has an 'any' type" in TypeScript Object Indexing
Learn why TypeScript rejects string object indexing and how to fix it with keyof, unions, and typed object keys in React.
Fix "Property has no initializer" in Angular TypeScript Components
Learn why Angular TypeScript shows "Property has no initializer" and how to fix it using defaults, optional properties, or definite assignment.