Question
In TypeScript, what does keyof typeof mean, and how does it work in a case like this?
enum ColorsEnum {
white = '#ffffff',
black = '#000000',
}
type Colors = keyof typeof ColorsEnum;
In this example, Colors becomes:
type Colors = "white" | "black";
I want to understand why that happens.
I would expect typeof ColorsEnum to return something like "Object", and then keyof "Object" would not seem very useful. Clearly, that is not how TypeScript is interpreting it. What exactly do typeof and keyof mean here, and why do they produce the union of enum member names?
Short Answer
By the end of this page, you will understand that typeof in TypeScript can refer to the type of a value, not JavaScript's runtime string result, and keyof extracts the property names from that type. Together, keyof typeof SomeValue turns an object-like value such as an enum or object literal into a union of its keys, like "white" | "black".
Concept
In TypeScript, typeof and keyof are both type operators, but they do different jobs.
typeof valuegets the TypeScript type of a valuekeyof SomeTypegets a union of the property names of a type
The important point is that this is not the same as JavaScript runtime behavior.
typeof in JavaScript vs TypeScript
In JavaScript:
typeof ColorsEnum // "object"
That returns a runtime string.
In TypeScript type positions:
type T = typeof ColorsEnum;
This does not produce the string "object". Instead, it produces the type shape of the ColorsEnum value.
For this enum:
enum ColorsEnum {
white = ,
black = ,
}
Mental Model
Think of it like this:
- A value is a real object sitting on a table
typeofis you looking at that object and writing down its shapekeyofis then reading that written shape and listing its labels
For example, imagine a toolbox:
const tools = {
hammer: 1,
screwdriver: 2,
};
typeof toolssays: “This thing has drawers namedhammerandscrewdriver.”keyof typeof toolssays: “Give me the drawer names only.”
Result:
"hammer" | "screwdriver"
So with keyof typeof, you are not asking JavaScript what kind of thing something is at runtime. You are asking TypeScript to inspect a value's structure and turn its property names into a type.
Syntax and Examples
Core syntax
type Keys = keyof typeof someValue;
This works when someValue is a value known to TypeScript, such as:
- an enum
- an object literal
- an imported constant object
Example with an enum
enum ColorsEnum {
white = '#ffffff',
black = '#000000',
}
type Colors = keyof typeof ColorsEnum;
// "white" | "black"
Explanation:
typeof ColorsEnumgets the type of the enum objectkeyofextracts its keys- The final result is a union of enum member names
Example with an object
const config = {
host: 'localhost',
port: 3000,
secure: true,
};
type = keyof config;
Step by Step Execution
Consider this example:
enum ColorsEnum {
white = '#ffffff',
black = '#000000',
}
type EnumType = typeof ColorsEnum;
type ColorKeys = keyof EnumType;
Now walk through it.
Step 1: Define the enum
enum ColorsEnum {
white = '#ffffff',
black = '#000000',
}
At runtime, this creates an object-like value with properties:
whiteblack
Step 2: Apply typeof
type EnumType = typeof ColorsEnum;
TypeScript reads the value ColorsEnum and gets its type.
You can think of EnumType as roughly:
Real World Use Cases
keyof typeof is common whenever you want to keep values and types in sync.
1. Enum key validation
enum Status {
pending = 'PENDING',
done = 'DONE',
}
type StatusKey = keyof typeof Status;
Useful when you want accepted strings to exactly match enum member names.
2. Configuration keys
const settings = {
theme: 'dark',
language: 'en',
notifications: true,
};
type SettingKey = keyof typeof settings;
This helps when writing functions that receive a valid config key.
3. Form field names
const fields = {
email: '',
password: '',
confirmPassword: '',
};
type FieldName = keyof typeof fields;
Real Codebase Usage
In real projects, developers often use keyof typeof to avoid repeating string unions manually.
Common pattern: derive types from constants
Instead of this:
type Theme = 'light' | 'dark';
const themes = {
light: '#fff',
dark: '#000',
};
developers often write:
const themes = {
light: '#fff',
dark: '#000',
};
type Theme = keyof typeof themes;
Now the keys and the type stay synchronized.
Guard clauses with known keys
const messages = {
success: 'Saved',
error: 'Failed',
};
type MessageKey = keyof typeof messages;
function getMessage(key: ) {
messages[key];
}
Common Mistakes
Mistake 1: Confusing TypeScript typeof with JavaScript typeof
Broken expectation:
type T = typeof ColorsEnum;
// expecting "object"
Why it is wrong:
- In JavaScript expressions,
typeof valuereturns a string like"object" - In TypeScript type positions,
typeof valuereturns the value's type
How to avoid it:
- Ask yourself whether you are in a runtime expression or a type annotation/type alias
Mistake 2: Using keyof directly on a value name
Broken code:
const user = {
name: 'Ada',
age: 30,
};
type UserKeys = keyof user;
Why it fails:
keyofworks on a type, not directly on a value
Comparisons
Related operators and patterns
| Pattern | What it gives you | Example result |
|---|---|---|
typeof value | The type of a value | { white: string; black: string } |
keyof Type | The keys of a type | `"white" |
keyof typeof value | The keys of a value's type | `"white" |
(typeof value)[keyof typeof value] | The value types of a value | string or specific value types |
keyof typeof vs manual union
| Approach |
|---|
Cheat Sheet
Quick reference
Get keys from an enum or object
type Keys = keyof typeof someValue;
Example with enum
enum ColorsEnum {
white = '#ffffff',
black = '#000000',
}
type ColorKeys = keyof typeof ColorsEnum;
// "white" | "black"
Example with object
const config = {
host: 'localhost',
port: 3000,
};
type ConfigKeys = keyof typeof config;
// "host" | "port"
Get values instead of keys
type Values = (typeof someValue)[keyof typeof someValue];
Important rules
keyofworks on
FAQ
What does keyof typeof mean in TypeScript?
It means: first get the type of a value using typeof, then get that type's property names using keyof.
Why does typeof not return "object" here?
Because in a type context, TypeScript's typeof is a type operator, not JavaScript's runtime operator. It returns the value's type shape, not a runtime string.
Does keyof typeof work only with enums?
No. It also works with object literals, imported constant objects, and other named values that TypeScript can inspect.
Does keyof typeof ColorsEnum give enum keys or enum values?
It gives the enum keys, such as "white" | "black", not the values like "#ffffff" | "#000000".
How do I get the values instead of the keys?
Use indexed access:
type ColorValues = (typeof ColorsEnum)[keyof typeof ColorsEnum];
Mini Project
Description
Build a small TypeScript utility that stores application status labels and lets you safely look them up by name. This demonstrates how keyof typeof can create a type directly from an object so only valid status names are accepted.
Goal
Create a type-safe status lookup function that only accepts keys defined in a status map.
Requirements
- Define a constant object containing at least three status labels.
- Create a type from the object's keys using
keyof typeof. - Write a function that accepts only valid status keys.
- Return the corresponding label from the object.
- Show at least one valid call and one invalid call in comments.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular @ViewChild Returning Undefined: Lifecycle, Child Components, and Fixes
Learn why Angular @ViewChild can be undefined, when it becomes available, and how to access child components correctly using lifecycle hooks.