The simplest way to convert TypeScript enum to number values is to read the member itself: a numeric enum member already is a number at runtime, so const n: number = OrderStatus.Shipped works with no cast. String enums are different, and need a lookup map:
const n: number = OrderStatus.Shipped; // 2
Nothing below is hand-typed output: I ran each file through TypeScript 7.0.2 and Node.js v22.22.2 with --strict on, then copied the console text.
Convert a numeric enum to a number
Members of a numeric enum get numbers automatically, starting at 0 unless you set a value. Here Pending starts at 1, so the next two count up:
enum OrderStatus {
Pending = 1,
Shipped, // 2
Delivered, // 3
Cancelled = 9,
}
const current = OrderStatus.Shipped;
const a: number = current; // no cast needed
const b = Number(current); // explicit
const c = +current; // unary plus
console.log(a, b, c, typeof a);
console.log("next step:", OrderStatus.Shipped + 1);
console.log(JSON.stringify({ orderId: 50217, city: "Denver", status: current }));
Output:
2 2 2 number
next step: 3
{"orderId":50217,"city":"Denver","status":2}

2, and typeof confirms it’s a plain number.Number() and + don’t change the value; they just make the intent obvious. It’s also what lands in JSON. For the basics of declaring enums, see my TypeScript enums guide.
Why does an enum name string fail to index the enum?
Names often arrive as text, say from a CSV column. Indexing the enum with a plain string doesn’t compile in strict mode:
enum OrderStatus { Pending = 1, Shipped, Delivered, Cancelled = 9 }
const fromCsv: string = "Shipped";
const code = OrderStatus[fromCsv];
Output:
enum_keyfail.ts(4,26): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.

string could be anything, so TypeScript won’t index the enum with it.The compiler needs a key it can trust. Turning free text into an actual enum member is its own topic, which I cover in converting a string to an enum in TypeScript.
Convert an enum name to its number with keyof typeof
keyof typeof OrderStatus gives the union of member names. A known literal works directly; untrusted input needs a check first:
enum OrderStatus { Pending = 1, Shipped, Delivered, Cancelled = 9 }
type StatusName = keyof typeof OrderStatus; // "Pending" | "Shipped" | ...
const known: StatusName = "Delivered";
console.log("known name:", OrderStatus[known]);
function statusCode(name: string): number | undefined {
if (!Object.hasOwn(OrderStatus, name)) return undefined;
const value = OrderStatus[name as StatusName];
return typeof value === "number" ? value : undefined;
}
for (const input of ["Shipped", "shipped", "toString", "2"]) {
console.log(JSON.stringify(input).padEnd(11), "->", statusCode(input));
}
console.log('OrderStatus["2"] =', (OrderStatus as Record<string, unknown>)["2"]);
Output:
known name: 3
"Shipped" -> 2
"shipped" -> undefined
"toString" -> undefined
"2" -> undefined
OrderStatus["2"] = Shipped
Object.hasOwn() blocks inherited names like toString. The typeof check matters because numeric enums also store reverse entries, so "2" returns the name Shipped, not a number. That’s explained in reverse mapping in TypeScript enums.
If keyof typeof looks odd, my keyof operator guide breaks it down.
Convert a string enum to a number
String enum members hold text, so Number() and + compile fine but quietly return NaN. Map each member to its number instead:
enum Plan {
Basic = "BASIC",
Pro = "PRO",
Team = "TEAM",
}
console.log("Number(Plan.Pro):", Number(Plan.Pro));
console.log("+Plan.Pro: ", +Plan.Pro);
const planTier: Record<Plan, number> = {
[Plan.Basic]: 1,
[Plan.Pro]: 2,
[Plan.Team]: 3,
};
const monthlyUsd: Record<Plan, number> = {
[Plan.Basic]: 9,
[Plan.Pro]: 29.5,
[Plan.Team]: 79.99,
};
for (const p of Object.values(Plan)) {
console.log(p.padEnd(5), "tier", planTier[p], `$${monthlyUsd[p].toFixed(2)}`);
}
enum ZipPrefix { Chicago = "606", Austin = "787" } // digits stored as text
const prefix = Number(ZipPrefix.Austin);
console.log("Austin prefix:", prefix, Number.isNaN(prefix) ? "(not numeric)" : "(ok)");
Output:
Number(Plan.Pro): NaN
+Plan.Pro: NaN
BASIC tier 1 $9.00
PRO tier 2 $29.50
TEAM tier 3 $79.99
Austin prefix: 787 (ok)

Number(Plan.Pro) is NaN; the Record<Plan, number> maps return real numbers.Record<Plan, number> also protects you later. If you add a member to Plan, the compiler flags every map that’s missing it. When the text is digits, like ZIP prefixes, Number() works, but still check for NaN.
More string parsing rules are in converting a string to a number in TypeScript. Need several values per member? See enums with multiple values.
Get a number from a const enum
A const enum disappears at compile time. TypeScript pastes the number wherever you use a member, which you can see in the emitted JavaScript:
const enum Speed {
Slow = 25,
Normal = 55,
Highway = 70,
}
const limit: number = Speed.Highway;
console.log("limit:", limit, "mph");
Output:
"use strict";
const limit = 70 /* Speed.Highway */;
console.log("limit:", limit, "mph");
limit: 70 mph

Speed object, just 70 and a comment with the member name.With no object at runtime, there’s no reverse mapping or Object.values(). The compiler stops a reverse lookup, and an out-of-range literal too:
const enum Speed { Slow = 25, Normal = 55, Highway = 70 }
const typed: Speed = 99;
const label = Speed[70];
Output:
enum_constfail.ts(3,7): error TS2322: Type '99' is not assignable to type 'Speed'.
enum_constfail.ts(4,21): error TS2476: A const enum member can only be accessed using a string literal.
Tools that compile one file at a time (isolatedModules) restrict const enums, so I keep them for internal constants.
Check that a number is a valid enum value
Going the other way is where bugs hide. A literal 7 is rejected, but any number variable is accepted, so values from an API slip through:
enum OrderStatus { Pending = 1, Shipped, Delivered, Cancelled = 9 }
const fromApi: number = 7;
const unchecked: OrderStatus = fromApi; // compiles, but 7 isn't a member
console.log("unchecked:", unchecked, OrderStatus[unchecked]);
const codes = Object.values(OrderStatus).filter(
(v): v is OrderStatus => typeof v === "number"
);
console.log("all codes:", codes);
function isOrderStatus(n: number): n is OrderStatus {
return (codes as number[]).includes(n);
}
for (const n of [2, 7, 9]) {
console.log(n, isOrderStatus(n) ? `valid (${OrderStatus[n]})` : "rejected");
}
Output:
unchecked: 7 undefined
all codes: [ 1, 2, 3, 9 ]
2 valid (Shipped)
7 rejected
9 valid (Cancelled)
Filtering Object.values() to numbers drops the reverse-mapping names, and the n is OrderStatus guard narrows the type. The pattern is explained in the is keyword in TypeScript, and listing members is in getting all enum values.
Which enum to number method should you use?
| Enum kind | How to get the number | Watch out for |
|---|---|---|
| Numeric enum | Read the member, or Number() for clarity | number values aren’t checked |
| Name as a string | keyof typeof + Object.hasOwn | Reverse-mapping keys like "2" |
| String enum | Record<Enum, number> map | Number() returns NaN |
| Const enum | Read the member (inlined) | No runtime object at all |
For switch logic over the codes, see switch statements on TypeScript enums. If you keep writing converters, enums vs string literal unions may change your mind.
These enum guides pair well with this one:
- Get an enum key by value in TypeScript
- Check if a string is in an enum
- Work with key-value pairs in TypeScript
- Convert a TypeScript enum to a string
Frequently asked questions
How do I convert a TypeScript enum to a number?
For a numeric enum, read the member: const n: number = Status.Active. It’s already a number, so Number() is optional.
Why does Number() return NaN for my enum?
It’s a string enum, so the member holds text like "PRO". Use a Record<Enum, number> lookup map instead.
How do I get the number from an enum name string?
Check the name with Object.hasOwn(), index with name as keyof typeof Enum, and confirm typeof value === "number".
Can I convert a const enum member to a number?
Yes. The compiler inlines the number, so const n: number = Speed.Highway becomes 70. Reverse lookups aren’t possible.
Does TypeScript check that a number is a valid enum value?
Only for literals. A number variable is assignable to a numeric enum without a check, so validate it with a type guard.
Where are TypeScript enums documented?

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn