type Join = K extends string | number ? P extends string | number ? `${K}${"" extends P ? "" : "."}${P}` : never : never; type DeepKeyof = T extends object ? { [K in keyof T]-?: K extends string | number ? (DeepKeyof extends infer DP ? DP extends string ? Join : K : K) : never }[keyof T] : ""; interface UserData { id: string; info: { name: { first: string; last: string; }; contact: { email: string; phone?: string; }; }; settings: { theme: 'dark' | 'light'; notifications: boolean; }; tags: string[]; } // Example Usage: type UserDataPaths = DeepKeyof; /* UserDataPaths will be a union of string literals like: "id" | "info" | "settings" | "tags" | "info.name" | "info.contact" | "info.name.first" | "info.name.last" | "info.contact.email" | "info.contact.phone" | "settings.theme" | "settings.notifications" */ // Function that takes a path to access a value (demonstrates usage) function getDeepValue>(obj: T, path: P): any { const parts = (path as string).split('.'); let current: any = obj; for (const part of parts) { if (current === null || typeof current !== 'object' || !(part in current)) { return undefined; } current = current[part]; } return current; } const myUser: UserData = { id: 'u1', info: { name: { first: 'John', last: 'Doe' }, contact: { email: 'john@example.com' } }, settings: { theme: 'dark', notifications: true }, tags: ['admin'] }; const userNameFirst = getDeepValue(myUser, 'info.name.first'); // Type-safe path access const userTheme = getDeepValue(myUser, 'settings.theme'); // Type-safe path access // const invalidPath = getDeepValue(myUser, 'info.name.middle'); // Error: Argument of type '"info.name.middle"' is not assignable to parameter of type 'DeepKeyof'