Keyof Operator
In this page:
Basic keyof
For an object type, keyof produces a union containing its known property names as string literal types, letting code work generically with 'any valid key of this type' instead of a fixed, hardcoded key.
Example: Basic keyof
interface User {
id: number;
name: string;
}
type UserKeys = keyof User; // "id" | "name"
let key: UserKeys = "name";
console.log(key);
keyof with Generic Functions
The K extends keyof T pattern ensures that a supplied key genuinely exists on the object type T, catching typos in a property name at compile time instead of returning undefined silently at runtime.
Example: keyof with Generic Functions
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const user = { id: 1, name: "Wei" };
console.log(getProperty(user, "name"));
keyof and Return Types
The indexed access type T[K] represents the type of the property selected by K, so a function's return type can automatically match whatever property was actually requested, rather than being widened to any.
Example: keyof and Return Types
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { id: 1, name: "Wei" };
const name: string = getProperty(user, "name");
console.log(name);
keyof for Updating Properties
The same K extends keyof T pattern can type both a selected property key and its matching value together, which is exactly what a type-safe generic getter or setter function needs.
Example: keyof for Updating Properties
function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): void {
obj[key] = value;
}
const user = { id: 1, name: "Wei" };
setProperty(user, "name", "Lin");
console.log(user);
keyof with Interfaces
Interfaces can be combined with keyof and generics to build reusable property-reading utilities that stay fully type-checked across any interface shape they're applied to.
Example: keyof with Interfaces
interface Product {
id: number;
price: number;
}
function getValue<K extends keyof Product>(product: Product, key: K) {
return product[key];
}
console.log(getValue({ id: 1, price: 20 }, "price"));
Keyof with Mapped Types
A mapped type can iterate over keyof T using the syntax { [K in keyof T]: ... }, which visits every property name of T one at a time, letting a new type be generated that mirrors T's keys while transforming each property's value type.
Example: Keyof with Mapped Types
interface User {
id: number;
name: string;
}
type ReadonlyUser = { readonly [K in keyof User]: User[K] };
const user: ReadonlyUser = { id: 1, name: "Sana" };
console.log(user);
The typeof Operator
In a type position, typeof takes an existing variable or constant and produces the type TypeScript already inferred for it, which avoids re-declaring a type by hand and keeps the type automatically in sync whenever the value's shape changes.
Example: The typeof Operator
const config = { retries: 3, timeout: 1000 };
type ConfigType = typeof config; // { retries: number; timeout: number }
let another: ConfigType = { retries: 5, timeout: 2000 };
console.log(another);
Keyof Typeof Pattern
Combining keyof with typeof, as in keyof typeof someObject, produces a union of a runtime object's own property names as string literal types, which is a common way to derive a type-safe key set directly from a plain JavaScript object.
Example: Keyof Typeof Pattern
const colors = { red: "#f00", green: "#0f0" };
type ColorKey = keyof typeof colors; // "red" | "green"
let key: ColorKey = "red";
console.log(colors[key]);
Keyof with Generic Constraints on Records
The keyof operator also works well with Record<K, V> and multiple type parameters, letting a function constrain one generic parameter to be a key of another, which is useful for utilities that operate generically over any object's keys and values together.
Example: Keyof with Generic Constraints on Records
function getFromRecord<K extends keyof R, R extends Record<string, number>>(record: R, key: K) {
return record[key];
}
const scores = { math: 90, science: 85 };
console.log(getFromRecord(scores, "math"));
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: