typescript / expert
Snippet
Deep Nested Property Path Type Resolution with Non-Distributive Conditionals
This advanced snippet uses template literal types and recursive conditional types to generate all valid nested property dot-paths of an object type. Wrapping the generic type parameter T in a single-element tuple [T] prevents TypeScript from distributing conditional types over union types, guaranteeing stable recursive evaluation without breaking type inference.
snippet.ts
typescript
1
2
3
4
type PathImpl<T, K extends keyof T> = K extends string ? (T[K] extends Record<string, any> ? K | `${K}.${PathImpl<T[K], keyof T[K]>}` : K) : never;type ObjectPath<T> = [T] extends [never] ? never : T extends object ? { [K in keyof T]: PathImpl<T, K> }[keyof T] : never;interface UserProfile { id: string; settings: { theme: 'dark' | 'light'; notifications: { email: boolean } }; }type ValidPaths = ObjectPath<UserProfile>;
Breakdown
1
type PathImpl<T, K extends keyof T> = K extends string ? (T[K] extends Record<string, any> ? K | `${K}.${PathImpl<T[K], keyof T[K]>}` : K) : never;
Recursively builds dot-separated property paths using template literal string interpolations.
2
type ObjectPath<T> = [T] extends [never] ? never : T extends object ? { [K in keyof T]: PathImpl<T, K> }[keyof T] : never;
Uses tuple wrapping [T] to suppress distributivity over unions and extracts all key paths into a union.
3
type ValidPaths = ObjectPath<UserProfile>;
Evaluates to the union string type 'id' | 'settings' | 'settings.theme' | 'settings.notifications' | 'settings.notifications.email'.