keyof T
The keyof type operator produces a union of all known public property keys of a type, enabling type-safe property access patterns.
Definition
type Keys = keyof { name: string; age: number };
// "name" | "age"Examples
interface User {
id: number;
name: string;
email: string;
}
type UserKey = keyof User;
// "id" | "name" | "email"
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user: User = { id: 1, name: "Alice", email: "[email protected]" };
const name = getProperty(user, "name"); // string
const id = getProperty(user, "id"); // numberfunction pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
const result = {} as Pick<T, K>;
keys.forEach((key) => {
result[key] = obj[key];
});
return result;
}
const user = { id: 1, name: "Alice", email: "[email protected]", password: "secret" };
const safe = pick(user, ["id", "name", "email"]);
// { id: number; name: string; email: string }interface Theme {
primary: string;
secondary: string;
background: string;
text: string;
}
const themeKeys: (keyof Theme)[] = [
"primary", "secondary", "background", "text",
];
function validateTheme(theme: Record<string, string>): theme is Theme {
return themeKeys.every((key) => typeof theme[key] === "string");
}Common Use Cases
- 1Type-safe property access with indexed types
- 2Constraining generic type parameters to valid keys
- 3Building dynamic property lookup functions
- 4Iterating over known properties for validation
- 5Creating mapped types and utility type definitions
Understanding keyof T
The keyof type operator takes an object type and produces a union of its known public property keys as string literal types. For an interface with properties "name", "age", and "email", keyof produces "name" | "age" | "email".
keyof is fundamental to TypeScript's type-safe property access pattern. The generic function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] is the canonical example: it accepts any object and any valid key for that object, and the return type T[K] (indexed access type) automatically resolves to the correct property type.
This pattern eliminates an entire class of bugs. Without keyof, accessing obj[key] would require key to be typed as string, and the return type would be any. With keyof, the compiler verifies that key is actually a valid property name and knows the exact type of the returned value.
keyof interacts with index signatures in specific ways. If a type has a string index signature, keyof produces string | number (since numeric keys are a subset of string keys in JavaScript). If it has a numeric index signature, keyof produces number. For types with only known properties, keyof produces the union of literal key types.
keyof is the building block of mapped types. The syntax [K in keyof T] iterates over every key, and this iteration pattern powers Partial, Required, Readonly, Pick, and all other mapped utility types. Understanding keyof is essential to understanding how these utility types work.
Combined with template literal types, keyof enables advanced key transformations. You can generate getter names, event handler names, or any other derived key pattern from the original keys of a type.
Related Types
typeof (Type Operator)The typeof type operator extracts the TypeScript type from a value-level variable or expression, bridging the value and type worlds.
Mapped TypesMapped types iterate over the keys of a type to create a new type by transforming each property, enabling systematic type transformations.
Pick<T, K>Constructs a type by picking the set of properties K from T, creating a subset of the original type.
Record<K, T>Constructs an object type whose property keys are K and whose property values are T, useful for dictionaries and lookup maps.
More Advanced Patterns
Explore TypeScript Types
Browse our complete reference of 30 TypeScript utility types with definitions, examples, and explanations.