Skip to content

Instantly share code, notes, and snippets.

@timvandam
Created January 13, 2024 15:36
Show Gist options
  • Save timvandam/55c73e2f52db80b5931d184c08889625 to your computer and use it in GitHub Desktop.
Save timvandam/55c73e2f52db80b5931d184c08889625 to your computer and use it in GitHub Desktop.
TypeScript getNestedObjectProperty
type JoinPath<A extends readonly string[]> = A extends readonly [infer K]
? K extends string
? K
: never
: A extends readonly [infer K, ...infer Rest]
? K extends string
? Rest extends readonly string[]
? `${K}.${JoinPath<Rest>}`
: never
: never
: never;
type SplitPath<A extends string> = A extends `${infer K}.${infer Rest}`
? [K, ...SplitPath<Rest>]
: A extends string
? readonly [A]
: never;
type NestedObjectPath<T, Path extends readonly string[] = []> = T extends object
?
| {
[K in keyof T & string]: T[K] extends object ? NestedObjectPath<T[K], [...Path, K]> : JoinPath<[...Path, K]>;
}[keyof T & string]
| JoinPath<Path>
: never;
type NestedObjectValue<T, Path extends NestedObjectPath<T>> = [Path] extends [never]
? T
: SplitPath<Path> extends readonly [infer K, ...infer Rest]
? K extends keyof T
? Rest extends readonly string[]
? NestedObjectValue<T[K], JoinPath<Rest> & NestedObjectPath<T[K]>>
: never
: never
: never;
function getNestedObjectProperty<T, const Path extends NestedObjectPath<T>>(
obj: T,
path: Path,
): NestedObjectValue<T, Path> {
return path.split('.').reduce((o: any, i) => o[i], obj);
}
const kekw = getNestedObjectProperty({ a: { b: { c: 1 } } }, 'a.b.c');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment