Skip to content

Instantly share code, notes, and snippets.

@millsp
Last active July 10, 2022 06:45
Show Gist options
  • Save millsp/1eec03fbe64592c70efa4c80515f741f to your computer and use it in GitHub Desktop.
Save millsp/1eec03fbe64592c70efa4c80515f741f to your computer and use it in GitHub Desktop.
Dotted paths with ts-toolbelt
import {
A,
F,
B,
O,
I,
} from 'ts-toolbelt';
type OnlyUserKeys<O> =
O extends L.List
? keyof O & number
: O extends M.BuiltInObject
? never
: keyof O & (string | number)
type PathsDot<O, I extends I.Iteration = I.IterationOf<'0'>> =
9 extends I.Pos<I> ? never :
O extends object
? {[K in keyof O & OnlyUserKeys<O>]:
`${K}` | `${K}.${PathsDot<O[K], I.Next<I>>}`
}[keyof O & OnlyUserKeys<O>]
: never
type PathDot<O, P extends string, strict extends B.Boolean = 1> =
P extends `${infer K}.${infer Rest}`
? PathDot<O.At<O & {}, K, strict>, Rest, strict>
: O.At<O & {}, P, strict>;
type Obj = {
a: Obj[],
b: { c: Obj},
d: 40
e: 50
};
declare const object: Obj;
declare function get<O extends object, P extends string>(
obj: O, path: A.Cast<P, PathsDot<O>>
): PathDot<O, P>;
const test0 = get(object, 'a.45.b.c.a.100.a.45.e');
const test1 = get(object, 'a.45.b.c.a.100.a.45.x');
@millsp
Copy link
Author

millsp commented Mar 26, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment