π 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 :
