Skip to content

Instantly share code, notes, and snippets.

@jRimbault
Last active November 21, 2021 12:55
Show Gist options
  • Save jRimbault/674fea1c06c983f4f12128555f1c1452 to your computer and use it in GitHub Desktop.
Save jRimbault/674fea1c06c983f4f12128555f1c1452 to your computer and use it in GitHub Desktop.
export type DeepDotKey<T> = {
[P in keyof T]: DeepDotKey<T[P]>;
} & (() => string);
/**
* Type safe string builder deep dot notation
*
* @example
* interface Foo {
* dictionary: { [key: string]: { value: number } | undefined };
* field: { prop: number };
* list: { node: string }[];
* }
*
* const _ = dot<Foo>();
* const key1 = _.field.prop(); // key1 === 'field.prop'
* const key2 = _.dictionary['hello'].value(); // key2 === 'dictionary.hello.value'
* const key3 = _.list[3].node(); // key3 === 'list.3.node'
*/
export function dot<T>(prev?: string): DeepDotKey<T> {
return new Proxy(() => prev, {
get: (_, next: string) => dot(prev ? `${prev}.${next}` : next),
}) as DeepDotKey<T>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment