import { Join } from "type-fest"; export type PathTo> = PathValue extends T ? Path : never interface PathArray extends ArrayLike { ["0"]?: keyof T; ["1"]?: L extends { ["0"]: infer K0; } ? K0 extends keyof T ? keyof T[K0] : never : never; ["2"]?: L extends { ["0"]: infer K0; ["1"]: infer K1; } ? K0 extends keyof T ? K1 extends keyof T[K0] ? keyof T[K0][K1] : never : never : never; ["3"]?: L extends { ["0"]: infer K0; ["1"]: infer K1; ["2"]: infer K2; } ? K0 extends keyof T ? K1 extends keyof T[K0] ? K2 extends keyof T[K0][K1] ? keyof T[K0][K1][K2] : never : never : never : never; ["4"]?: L extends { ["0"]: infer K0; ["1"]: infer K1; ["2"]: infer K2; ["3"]: infer K3; } ? K0 extends keyof T ? K1 extends keyof T[K0] ? K2 extends keyof T[K0][K1] ? K3 extends keyof T[K0][K1][K2] ? keyof T[K0][K1][K2][K3] : never : never : never : never : never; ["5"]?: L extends { ["0"]: infer K0; ["1"]: infer K1; ["2"]: infer K2; ["3"]: infer K3; ["4"]: infer K4; } ? K0 extends keyof T ? K1 extends keyof T[K0] ? K2 extends keyof T[K0][K1] ? K3 extends keyof T[K0][K1][K2] ? K4 extends keyof T[K0][K1][K2][K3] ? keyof T[K0][K1][K2][K3][K4] : never : never : never : never : never : never; ["6"]?: L extends { ["0"]: infer K0; ["1"]: infer K1; ["2"]: infer K2; ["3"]: infer K3; ["4"]: infer K4; ["5"]: infer K5; } ? K0 extends keyof T ? K1 extends keyof T[K0] ? K2 extends keyof T[K0][K1] ? K3 extends keyof T[K0][K1][K2] ? K4 extends keyof T[K0][K1][K2][K3] ? K5 extends keyof T[K0][K1][K2][K3][K4] ? keyof T[K0][K1][K2][K3][K4][K5] : never : never : never : never : never : never : never; } type ArrayHasIndex = { [K in MinLenght]: any }; export type PathArrayValue< T, L extends PathArray > = L extends ArrayHasIndex<0 | 1 | 2 | 3 | 4 | 5 | 6 | 7> ? any : L extends ArrayHasIndex<0 | 1 | 2 | 3 | 4 | 5 | 6> ? T[L[0]][L[1]][L[2]][L[3]][L[4]][L[5]][L[6]] : L extends ArrayHasIndex<0 | 1 | 2 | 3 | 4 | 5> ? T[L[0]][L[1]][L[2]][L[3]][L[4]][L[5]] : L extends ArrayHasIndex<0 | 1 | 2 | 3 | 4> ? T[L[0]][L[1]][L[2]][L[3]][L[4]] : L extends ArrayHasIndex<0 | 1 | 2 | 3> ? T[L[0]][L[1]][L[2]][L[3]] : L extends ArrayHasIndex<0 | 1 | 2> ? T[L[0]][L[1]][L[2]] : L extends ArrayHasIndex<0 | 1> ? T[L[0]][L[1]] : L extends ArrayHasIndex<0> ? T[L[0]] : never; export type Path = PathArray | keyof T | Join; export type PathValue> = L extends PathArray ? PathArrayValue : L extends keyof T ? T[L] : any; export function normalizePath(path: Path): Array { if (typeof path == 'string') { return path.split(/[.[\]]+|\./).filter(Boolean); } else if (Array.isArray(path)) { return path as any; } else { return [path] as any; } }