Using Mapped Types to Transform Index Types in TypeScript
This article explains how TypeScript index types work, demonstrates using mapped types to add modifiers like readonly, shows how to split index types into separate components with custom generic types, and provides recursive examples for extracting property paths, illustrating advanced type manipulation techniques.
Index types are a common TypeScript type that aggregates multiple elements such as objects, classes, tuples, etc.
For example:
type Person = {
name: string;
age: number;
hobbies: string[]
}Mapping types allow you to transform the keys and values of an index type to produce a new index type.
For instance, adding a readonly modifier to each property:
type ToReadonly<Obj> = {
readonly [Key in keyof Obj]: Obj[Key]
}The result is the modified index type.
TypeScript also provides many built‑in utility types based on mapped types, such as Partial and Required.
In summary, mastering mapped types lets you perform various transformations on index types.
However, these transformations still produce an index type as a whole.
Sometimes you need to split an index type so that each key is handled separately and the results are combined into a union.
Here is a custom generic that splits an object type into separate key‑value mappings:
type SplitObj<Obj> = {
[Key in keyof Obj]: {
[Key2 in Key]: Obj[Key2]
}
}[keyof Obj];Result:
Explanation: keyof Obj yields a union of keys (e.g., 'name' | 'age' | 'height'). The outer mapped type iterates over each key, and the inner mapped type processes the value, ultimately producing a union of the transformed keys.
Further, you can recursively walk an object type to generate a union of all property paths:
type DFS<Obj> = {
[Key in keyof Obj]: Key extends string ? Obj[Key] extends Record<string, any> ? Key | `${Key}.${DFS<Obj[Key]>}` : Key : never
}[keyof Obj];The conditional checks ensure that only string keys are processed and that recursion occurs only for nested object types.
The final result is a union of all property paths.
Review: this pattern is useful when you need to split each index, apply recursive processing, and then merge the results via a union type.
Summary
Index types are common in TypeScript and can be altered with mapped type syntax to generate new index types.
If you need to handle each key individually and merge the outcomes, you can add an extra layer of mapped types, process each key separately, and then use keyof to obtain a union of the processed keys.
This approach is handy in scenarios that require splitting index types, processing them independently, and recombining the results.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
