Question
I have defined the following enum in TypeScript:
enum Color {
Red,
Green
}
In a function, I receive a color value as a string. For example:
const green = "Green";
const color: Color = <Color>green; // Error: cannot convert string to enum
How can I safely convert a string value like "Green" into the corresponding Color enum value in TypeScript?
Short Answer
By the end of this page, you will understand why a plain string cannot be directly cast to a TypeScript enum, how enum lookup works, and how to safely convert strings into enum values using validation. You will also learn common patterns used in real TypeScript codebases to avoid runtime bugs.
Concept
TypeScript enums are named sets of constant values. In your example:
enum Color {
Red,
Green
}
Color.Red is actually 0, and Color.Green is 1 because numeric enums start at 0 by default.
That means this enum is not storing the strings "Red" and "Green". It is storing numeric values with named members.
So when you write:
const green = "Green";
const color: Color = green as Color;
TypeScript may allow a type assertion in some cases, but that does not actually convert the string at runtime. A type assertion only tells the compiler, "trust me." It does not change the value.
This matters because:
"Green"is a stringColor.Greenis the number
Mental Model
Think of an enum like a labeled storage rack:
- The label
Redpoints to value0 - The label
Greenpoints to value1
If someone gives you the text "Green", you do not automatically have the value 1. You first need to go to the rack and ask:
"Do you have a label named
Green? If yes, give me the value behind it."
That is what enum lookup does.
A type assertion like green as Color is like writing 1 on a sticky note and placing it on top of the string. The original value is still just the string "Green". Nothing has been converted.
Syntax and Examples
Basic enum lookup
enum Color {
Red,
Green
}
const input = "Green";
const color = Color[input as keyof typeof Color];
console.log(color); // 1
console.log(color === Color.Green); // true
How it works
typeof Colorgets the type of the enum objectkeyof typeof Colormeans the valid enum keys:"Red" | "Green"Color[input as keyof typeof Color]looks up the member by name
Safer version with validation
enum Color {
Red,
Green
}
function parseColor(: ): | {
(value && ((value))) {
[value keyof ] ;
}
;
}
.(());
.(());
Step by Step Execution
Consider this example:
enum Color {
Red,
Green
}
const input = "Green";
const result = Color[input as keyof typeof Color];
Here is what happens step by step:
- TypeScript compiles the numeric enum into an object similar to this:
{
0: "Red",
1: "Green",
Red: 0,
Green: 1
}
-
inputcontains the string"Green". -
input as keyof typeof Colortells TypeScript to treatinputas a valid enum key. -
Color["Green"]is evaluated. -
The enum object returns
1.
Real World Use Cases
String-to-enum conversion is common whenever your program receives text from outside your code.
Common examples
- API request parameters: a query string might contain
"Green" - Form input: a dropdown or text field may send enum names as strings
- Configuration files: JSON often stores values as strings
- URL parameters:
/products?color=Green - Environment variables: values always arrive as strings
- CLI tools: command-line options are text input
Example: parsing an API filter
enum Status {
Pending,
Approved,
Rejected
}
function parseStatus(value: string): Status | undefined {
if (value in Status && isNaN(Number(value))) {
return Status[value as keyof typeof Status] as Status;
}
return ;
}
Real Codebase Usage
In real projects, developers rarely cast raw input directly. They usually wrap conversion in a helper function and validate the input first.
Common patterns
Guard clause
function parseColor(value: string): Color | undefined {
if (!(value in Color) || !isNaN(Number(value))) {
return undefined;
}
return Color[value as keyof typeof Color] as Color;
}
This rejects invalid input early.
Validation before business logic
const parsedColor = parseColor(userInput);
if (parsedColor === undefined) {
throw new Error("Invalid color value");
}
saveColor(parsedColor);
Mapping external values to internal enums
Sometimes incoming values do not match enum member names exactly.
Common Mistakes
1. Thinking as converts the value
Broken example:
enum Color {
Red,
Green
}
const input = "Green";
const color = input as Color;
Problem:
- This does not convert
"Green"into1 - It only changes what TypeScript believes about the type
2. Skipping validation
Broken example:
const input = "Blue";
const color = Color[input as keyof typeof Color];
console.log(color); // undefined
Problem:
- invalid input leads to
undefined - later code may fail unexpectedly
Fix it by checking first.
Comparisons
Enum conversion approaches
| Approach | Works for numeric enum | Works for string enum | Safe by default | Notes |
|---|---|---|---|---|
value as Color | No real conversion | No real conversion | No | Type assertion only |
Color[value as keyof typeof Color] | Yes | Looks up by key, not value | No | Add validation |
Object.values(Color).includes(value as Color) | Limited | Yes | Better | Useful for string enums |
| Manual map object | Yes | Yes | Yes |
Cheat Sheet
Numeric enum lookup
enum Color {
Red,
Green
}
const input = "Green";
const color = Color[input as keyof typeof Color]; // 1
Safe parser for numeric enum
function parseColor(value: string): Color | undefined {
if (value in Color && isNaN(Number(value))) {
return Color[value as keyof typeof Color] as Color;
}
return undefined;
}
String enum parser
enum Color {
Red = ,
=
}
(): | {
.().(value )
? (value )
: ;
}
FAQ
How do I convert a string to an enum in TypeScript?
Use enum lookup or a parser function. For a numeric enum, Color[input as keyof typeof Color] looks up the enum member by name.
Why does as Color not work?
Because type assertions only affect TypeScript's type checking. They do not transform the runtime value.
What happens if the string does not match an enum member?
The lookup usually returns undefined, so you should validate the input first.
Is a string enum easier to use than a numeric enum?
Usually yes, especially for API data, JSON, and form values, because the runtime values are readable strings.
Can I do case-insensitive enum parsing?
Yes. Normalize the input first, or use a mapping object like { green: Color.Green }.
Should I use enums or string literal unions?
If you only need type safety, string literal unions are often simpler. If you want a grouped runtime object, enums can be useful.
Do numeric enums and string enums behave the same way?
No. Numeric enums support reverse mapping. String enums do not behave the same way at runtime.
Mini Project
Description
Build a small TypeScript utility that parses user-provided color strings into enum values. This demonstrates safe conversion, input normalization, and validation, which are all common when handling form input, query parameters, or API values.
Goal
Create a reusable parseColor function that converts a string into a valid Color enum value or returns undefined when the input is invalid.
Requirements
- Define a
Colorenum with at leastRed,Green, andBlue. - Accept user input as a string.
- Support case-insensitive input such as
"green"or"GREEN". - Return
undefinedfor invalid values. - Print a message showing whether parsing succeeded.
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.