🔑 TypeScript — Keyof Type Operator: Explained with Examples
🧲 Introduction – What Is the keyof Operator in TypeScript?
The keyof operator in TypeScript is a powerful tool for extracting the keys of a type as a union of string (or numeric) literal types. This allows you to build more dynamic, type-safe applications by referencing property names programmatically.
🎯 In this guide, you’ll learn:
- How the
keyofoperator works - Syntax and output patterns
- Use cases with objects, generics, and mapped types
- Real-world examples to deepen your understanding
🧱 What Is the keyof Type Operator?
The keyof operator takes an object type and returns a union of its property names as string or number literal types.
📌 Basic Syntax
type Keys = keyof ObjectType;
🧪 Example
type Point = { x: number; y: number };
type P = keyof Point; // "x" | "y"
keyof Pointextracts'x'and'y'as a union of string literal types.
📦 How Does keyof Work with Index Signatures?
If your object has an index signature, keyof behaves differently.
type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish; // number
type Mapish = { [k: string]: boolean };
type M = keyof Mapish; // string | number
Why string | number?
In JavaScript, all object keys are coerced to strings, so even obj[0] is treated as obj["0"].
🛠️ Practical Use in Generic Functions
You can use keyof to enforce type-safe key access in objects:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: "Alice", age: 30 };
const userName = getProperty(user, "name"); // ✅ OK
const invalid = getProperty(user, "email"); // ❌ Error
- Ensures
keyis one of the valid keys ofT, avoiding typos and runtime errors.
🔁 Combining keyof with Mapped Types
Mapped types often rely on keyof to iterate through object keys.
🔄 Example: Optional Properties
type Person = {
name: string;
age: number;
};
type OptionalPerson = {
[K in keyof Person]?: Person[K];
};
// Equivalent to: { name?: string; age?: number; }
🔁 Example: Readonly
type ReadonlyPerson = {
readonly [K in keyof Person]: Person[K];
};
These constructs help dynamically transform types based on their structure.
🎯 keyof in Real-World Use
Consider a deeply nested API response:
type APIResponse = {
user: {
id: string;
profile: {
email: string;
name: string;
}
}
};
type UserKeys = keyof APIResponse['user']; // "id" | "profile"
type ProfileKeys = keyof APIResponse['user']['profile']; // "email" | "name"
This usage ensures your access patterns remain strongly typed, even with nested structures.
🧠 keyof with Template Literals and Remapping
Using TypeScript 4.1+, you can even remap keys during iteration:
type Getter<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type Car = { brand: string; speed: number };
type CarGetters = Getter<Car>;
// Result: { getBrand: () => string; getSpeed: () => number }
This opens the door to highly dynamic and reusable utility types.
📌 Summary – Recap & Next Steps
The keyof operator unlocks the ability to dynamically reference and manipulate keys in TypeScript types.
🔍 Key Takeaways:
keyofreturns a union of an object’s property names.- Works great with generics, index signatures, and mapped types.
- Enables type-safe property access and dynamic type transformations.
⚙️ Real-world relevance:
Use keyof in utility types, form validation schemas, dynamic table headers, and API models to enforce type safety and reduce bugs.
❓ FAQs
❓ What does keyof return?
✅ A union of the keys of an object type as string or number literal types.
type Person = { name: string; age: number };
type P = keyof Person; // "name" | "age"
❓ Can keyof be used with nested types?
✅ Yes. You can chain key access with keyof and bracket notation.
type FriendKeys = keyof APIResponse['user']['profile']; // "email" | "name"
❓ Does keyof include symbol keys?
✅ By default, keyof includes string | number | symbol, but you can limit it using keyofStringsOnly in tsconfig.json.
❓ How is keyof different from typeof?
typeofis used to get the type of a valuekeyofis used to get the keys of a type
const user = { id: 1, name: "Alice" };
type UserKeys = keyof typeof user; // "id" | "name"
❓ Can keyof be used with arrays?
✅ Yes, especially with index signatures:
type Arrayish = { [n: number]: string };
type Keys = keyof Arrayish; // number
Share Now :
