Web Development TypeScript Subjective
Oct 04, 2025

How do you create a type that extracts all possible object paths?

Detailed Explanation
Object path extraction uses recursive conditional types with template literals to traverse object structure. Basic Path Extraction: type Paths = T extends object ? { [K in keyof T]: K extends string ? T[K] extends object ? K | `${K}.${Paths}` : K : never; }[keyof T] : never; type User = { id: number; profile: { name: string; address: { street: string; city: string; }; }; hobbies: string[]; }; type UserPaths = Paths; // 'id' | 'profile' | 'hobbies' | 'profile.name' | 'profile.address' | 'profile.address.street' | 'profile.address.city' Advanced Path Extraction with Array Handling: type PathsAdvanced = { [K in keyof T]: K extends string ? T[K] extends (infer U)[] ? `${Prefix}${K}` | `${Prefix}${K}.${number}` | PathsAdvanced : T[K] extends object ? `${Prefix}${K}` | PathsAdvanced : `${Prefix}${K}` : never; }[keyof T]; type ComplexObject = { users: { id: number; profile: { name: string; }; }[]; settings: { theme: string; }; }; type ComplexPaths = PathsAdvanced; // 'users' | 'settings' | 'users.0' | 'users.0.id' | 'users.0.profile' | 'users.0.profile.name' | 'settings.theme' Type-Safe Get Function: type PathValue = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathValue : never : P extends keyof T ? T[P] : never; function get>( obj: T, path: P ): PathValue { const keys = path.split('.'); let result: any = obj; for (const key of keys) { result = result?.[key]; } return result; } // Usage with type safety const user: User = { id: 1, profile: { name: 'John', address: { street: '123 Main St', city: 'New York' } }, hobbies: ['reading'] }; const name = get(user, 'profile.name'); // Type: string const city = get(user, 'profile.address.city'); // Type: string // const invalid = get(user, 'profile.invalid'); // Error! Set Function Implementation: function set>( obj: T, path: P, value: PathValue ): T { const keys = path.split('.'); let current: any = obj; for (let i = 0; i < keys.length - 1; i++) { current = current[keys[i]]; } current[keys[keys.length - 1]] = value; return obj; } // Usage set(user, 'profile.name', 'Jane'); // Type-safe // set(user, 'profile.name', 123); // Error: number not assignable to string Benefits: • Type-safe object property access • Compile-time path validation • Excellent autocomplete support • Prevents runtime property access errors.
Discussion (0)

No comments yet. Be the first to share your thoughts!

Share Your Thoughts
Feedback