The quickest TypeScript enum to array conversion is a single call: pass the enum to Object.values() for its values or Object.keys() for its names. A string enum gives you a clean array right away; a numeric enum needs one filter() first:
const values = Object.values(ShippingCarrier); // string enum
const names = Object.keys(OrderStatus).filter((k) => isNaN(Number(k))); // numeric enum
My setup for this page was TypeScript 7.0.2 and Node.js v22.22.2 with strict mode on, and the output blocks are pasted straight from my terminal.
You’ll see string and numeric enums, a typed helper, dropdown options, and why a const enum can’t be converted.
Convert a string enum to an array
A string enum compiles to a plain object, so the Object methods just work. Use Object.entries() when you need both the name and the value:
enum ShippingCarrier {
UPS = "ups",
FedEx = "fedex",
USPS = "usps",
}
const values = Object.values(ShippingCarrier);
const keys = Object.keys(ShippingCarrier);
const pairs = Object.entries(ShippingCarrier);
console.log("values: ", values);
console.log("keys: ", keys);
console.log("entries:", pairs);
Output:
values: [ 'ups', 'fedex', 'usps' ]
keys: [ 'UPS', 'FedEx', 'USPS' ]
entries: [ [ 'UPS', 'ups' ], [ 'FedEx', 'fedex' ], [ 'USPS', 'usps' ] ]
The values array is typed as ShippingCarrier[], so you can pass it anywhere the enum is expected. If you only need the values and want more ways to read them, I cover that in getting all enum values in TypeScript.
Why does a numeric enum array have extra items?
Numeric enums get a reverse mapping: TypeScript stores OrderStatus[0] = "Pending" as well as OrderStatus.Pending = 0. That’s why Object.values() returns six items for a three-member enum:
enum OrderStatus {
Pending, // 0
Shipped, // 1
Delivered, // 2
}
console.log("Object.values:", Object.values(OrderStatus));
const names = Object.keys(OrderStatus).filter((k) => isNaN(Number(k)));
const numbers = Object.values(OrderStatus).filter(
(v): v is OrderStatus => typeof v === "number"
);
console.log("names: ", names);
console.log("numbers:", numbers);
Output:
Object.values: [ 'Pending', 'Shipped', 'Delivered', 0, 1, 2 ]
names: [ 'Pending', 'Shipped', 'Delivered' ]
numbers: [ 0, 1, 2 ]

Object.values() mixes names and numbers; filtering on isNaN and typeof leaves the clean names and values.Keys that look like numbers are the reverse entries, so isNaN(Number(k)) keeps only the real names. The type guard v is OrderStatus keeps the result typed. The mechanism itself is explained in reverse mapping in TypeScript enums.
Write a typed enum-to-array helper
I keep two small generic functions so I never have to remember which filter goes with which enum. They work for string, numeric and mixed (heterogeneous) enums, with the enum’s own types:
function enumKeys<E extends Record<string, string | number>>(e: E): (keyof E)[] {
return Object.keys(e).filter((k) => isNaN(Number(k))) as (keyof E)[];
}
function enumValues<E extends Record<string, string | number>>(e: E): E[keyof E][] {
return enumKeys(e).map((k) => e[k]);
}
enum OrderStatus { Pending, Shipped, Delivered }
enum ShippingCarrier { UPS = "ups", FedEx = "fedex", USPS = "usps" }
enum PlanTier { Free = 0, Pro = "pro", Team = 25 } // mixed values
const statuses: OrderStatus[] = enumValues(OrderStatus);
console.log("numeric:", enumKeys(OrderStatus), statuses);
console.log("string: ", enumKeys(ShippingCarrier), enumValues(ShippingCarrier));
console.log("mixed: ", enumKeys(PlanTier), enumValues(PlanTier));
Output:
numeric: [ 'Pending', 'Shipped', 'Delivered' ] [ 0, 1, 2 ]
string: [ 'UPS', 'FedEx', 'USPS' ] [ 'ups', 'fedex', 'usps' ]
mixed: [ 'Free', 'Pro', 'Team' ] [ 0, 'pro', 25 ]

PlanTier enum.The trick is filtering keys, not values: a mixed enum can hold both strings and numbers, so a typeof check on values would drop real members. To loop over the members instead of collecting them, see how to iterate over enums in TypeScript.
Turn an enum into an array of objects for a dropdown
The most common real use is a select list. Map Object.entries() to { label, value } objects, then build the options. The same array validates form input:
enum ShippingCarrier {
UPS = "ups",
FedEx = "fedex",
USPS = "usps",
}
interface Option {
label: string;
value: ShippingCarrier;
}
const options: Option[] = Object.entries(ShippingCarrier).map(([label, value]) => ({
label,
value,
}));
console.log(options);
const html = options
.map((o) => `<option value="${o.value}">${o.label}</option>`)
.join("\n");
console.log(html);
const fromForm = "fedex";
const isCarrier = (s: string): s is ShippingCarrier =>
(Object.values(ShippingCarrier) as string[]).includes(s);
console.log(`"${fromForm}" is a carrier:`, isCarrier(fromForm));
console.log(`"dhl" is a carrier:`, isCarrier("dhl"));
Output:
[
{ label: 'UPS', value: 'ups' },
{ label: 'FedEx', value: 'fedex' },
{ label: 'USPS', value: 'usps' }
]
<option value="ups">UPS</option>
<option value="fedex">FedEx</option>
<option value="usps">USPS</option>
"fedex" is a carrier: true
"dhl" is a carrier: false

<option> tags, and the type guard accepting fedex while rejecting dhl.For numeric enums, build the entries from enumKeys() above so the numbers don’t show up as labels.
Going the other way, from a value back to its name, is covered in getting an enum key by value. A related check is checking if a value exists in an enum.
Can you convert a const enum to an array?
No. A const enum is inlined and erased at compile time, so there’s no object left to read:
const enum Region {
East = "east",
West = "west",
}
const regions = Object.values(Region);
Output:
enum_const.ts(6,31): error TS2475: 'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.

const enum in property or index access, so passing the whole enum fails.Need an array anyway? Use an as const array or object: one definition gives you a union type and a runtime array:
const REGIONS = ["east", "central", "west"] as const;
type Region = (typeof REGIONS)[number]; // "east" | "central" | "west"
const PRIORITY = { Low: 1, Normal: 2, Urgent: 3 } as const;
type Priority = (typeof PRIORITY)[keyof typeof PRIORITY]; // 1 | 2 | 3
const levels: Priority[] = Object.values(PRIORITY);
console.log("regions:", REGIONS);
console.log("priority values:", levels);
Output:
regions: [ 'east', 'central', 'west' ]
priority values: [ 1, 2, 3 ]
I now reach for this pattern in new code more often than enums. The trade-offs are laid out in enums vs string literal unions in TypeScript.
TypeScript enum to array methods compared
| Goal | Code | Works for |
|---|---|---|
| Values of a string enum | Object.values(E) | String enums |
| Names of any enum | Object.keys(E).filter(k => isNaN(Number(k))) | String, numeric, mixed |
| Values of a numeric enum | Object.values(E).filter(v => typeof v === "number") | Numeric enums |
| Typed keys and values | enumKeys(E) / enumValues(E) | All regular enums |
| Inlined constants as an array | as const array or object | Replaces const enum |
Once your enum is an array, these enum guides pick up the next problem:
- Convert a TypeScript enum to a string
- Use enums in a TypeScript switch statement
- Use TypeScript enums as object keys
- Convert an object to an array in TypeScript
Frequently asked questions
How do I get an array of enum values in TypeScript?
For a string enum, use Object.values(MyEnum). For a numeric enum, filter it with typeof v === "number" to drop the reverse-mapped names.
Why does Object.values return duplicates for a numeric enum?
Numeric enums also map each number back to its name. Filter out keys that parse as numbers.
How do I get the enum names as an array?
Use Object.keys(MyEnum).filter(k => isNaN(Number(k))). It works for string, numeric and mixed enums.
How do I convert an enum to an array of objects?
Map the entries: Object.entries(MyEnum).map(([label, value]) => ({ label, value })). That’s ready for a dropdown.
Can I use Object.values on a const enum?
No. A const enum doesn’t exist at runtime, so the compiler rejects it. Use an as const array or object instead.