type Exist = T extends undefined | null ? never : T; type ExtractFromObject, K> = K extends keyof O ? O[K] : K extends keyof Exist ? Exist[K] : never; type ExtractFromArray = any[] extends A ? A extends readonly (infer T)[] ? T | undefined : undefined : K extends keyof A ? A[K] : undefined; type GetWithArray = K extends [] ? O : K extends [infer Key, ...infer Rest] ? O extends Record ? GetWithArray, Rest> : O extends readonly any[] ? GetWithArray, Rest> : never : never; type Path = T extends `${infer Key}.${infer Rest}` ? [Key, ...Path] : T extends `${infer Key}` ? [Key] : []; // Type that generate a type of a value by a path; // e.g. ['a', 'b', 'c'] => { a: { b: { c: PropertyKey } } } // e.g. ['a', 'b', 'c', 'd'] => { a: { b: { c: { d: PropertyKey } } } } // e.g. ['a'] => { a: PropertyKey } // e.g. ['a', '0'], => { a: [PropertyKey] } // e.g. ['a', '0', 'b'] => { a: [{ b: PropertyKey }] } // e.g. ['a', '0', 'b', '0'] => { a: [{ b: [PropertyKey] }] } // e/g/ ['0', 'a'] => [{ a: PropertyKey }] // // Input: ['a', 'b', 'c'], constrain: PropertyKey // Output: { a: { b: { c: PropertyKey } } } export type UnionToIntersection = ( Union extends unknown ? (distributedUnion: Union) => void : never ) extends ((mergedIntersection: infer Intersection) => void) ? Intersection & Union : never; type PathToType = T extends [infer Head, ...infer Rest] ? Head extends string ? Head extends `${number}` ? Rest extends string[] ? PathToType[] : never : Rest extends string[] ? { [K in Head & string]: PathToType } : never : never : string; export type Generate = UnionToIntersection>>; type Get = GetWithArray>; export function getByPath(obj: O, path: K): Get; export function getByPath(obj: Record, path: string): unknown { const keys = path.split('.'); let currentObj = obj; for (const key of keys) { const value = currentObj[key]; if (value === undefined || value === null) return undefined; currentObj = value as Record; } return currentObj; }