TypeScript keyof
Extract object keys as types
🔑 What is keyof?
The keyof operator extracts all property keys from an object type as a union. It helps create type-safe code by ensuring you only use valid property names from objects.
type Person = { name: string; age: number };
type PersonKeys = keyof Person; // "name" | "age"
Key Concepts
Extract Keys
Get all property names as types
type User = { id: number; email: string };
type Keys = keyof User; // "id" | "email"
Type Safety
Prevent invalid property access
function getValue(obj: User, key: keyof User) {
return obj[key]; // Safe!
}
Dynamic Access
Access properties dynamically
const user = { id: 1, email: "[email protected]" };
getValue(user, "id"); // ✓ Valid
Error Prevention
Catch typos at compile time
getValue(user, "name");
// ✗ Error: "name" not in keyof User
🔹 Basic keyof Usage
Extract keys from an object type:
type Product = {
id: number;
name: string;
price: number;
};
type ProductKeys = keyof Product;
// Result: "id" | "name" | "price"
const key1: ProductKeys = "name"; // ✓ Valid
const key2: ProductKeys = "price"; // ✓ Valid
const key3: ProductKeys = "color"; // ✗ Error!
🔹 keyof with Functions
Create type-safe property accessors:
type Car = {
brand: string;
model: string;
year: number;
};
function getProperty(car: Car, key: keyof Car) {
return car[key];
}
const myCar: Car = {
brand: "Toyota",
model: "Camry",
year: 2023
};
console.log(getProperty(myCar, "brand")); // "Toyota"
console.log(getProperty(myCar, "year")); // 2023
// getProperty(myCar, "color"); // ✗ Error!
🔹 keyof with Generics
Make reusable type-safe functions:
function getPropertyGeneric<T, K extends keyof T>(
obj: T,
key: K
): T[K] {
return obj[key];
}
const user = { name: "Alice", age: 30 };
const userName = getPropertyGeneric(user, "name"); // string
const userAge = getPropertyGeneric(user, "age"); // number
🔹 keyof with Arrays and Tuples
keyof works with arrays and tuples too:
// With arrays
type ArrayKeys = keyof string[];
// Result: number | "length" | "push" | "pop" | ...
// With tuples
type Tuple = [string, number, boolean];
type TupleKeys = keyof Tuple;
// Result: "0" | "1" | "2" | "length" | ...
const tuple: Tuple = ["hello", 42, true];
const firstKey: TupleKeys = "0"; // ✓ Valid
const lengthKey: TupleKeys = "length"; // ✓ Valid
🔹 Practical Example
Build a type-safe update function:
type Settings = {
theme: "light" | "dark";
fontSize: number;
notifications: boolean;
};
function updateSetting<K extends keyof Settings>(
key: K,
value: Settings[K]
): void {
// Update logic here
console.log(`Updated ${key} to ${value}`);
}
updateSetting("theme", "dark"); // ✓ Valid
updateSetting("fontSize", 16); // ✓ Valid
updateSetting("notifications", true); // ✓ Valid
// updateSetting("theme", 123); // ✗ Error: wrong type
// updateSetting("color", "blue"); // ✗ Error: invalid key
💡 Key Takeaways
- keyof extracts all property keys as a union type
- Use it to create type-safe property access functions
- Combine with generics for reusable type-safe code
- Prevents typos and invalid property access at compile time