UNPKG

groq-builder

Version:

A **schema-aware**, strongly-typed GROQ query builder. It enables you to build GROQ queries using **auto-completion**, **type-checking**, and **runtime validation**.

29 lines (28 loc) 1.29 kB
/** * Extracts all deep paths of nested types. * * @example * type Keys = Path<{ a: { b: { c: "C" } } }>; * // Keys = "a" | "a.b" | "a.b.c" */ export type Path<T> = keyof T extends string ? PathImpl2<T> extends infer P ? P extends string | keyof T ? P : keyof T : keyof T : never; /** * Extracts the value of a deep path. * * @example * type Val = PathValue<{ a: { b: { c: "C" } } }, "a.b.c">; * // Val = "C"; */ export type PathValue<T, P extends Path<T>> = P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? Rest extends Path<T[Key]> ? PathValue<T[Key], Rest> : never : never : P extends keyof T ? T[P] : never; /** * Returns a deeply-flattened type * @example * PathEntries<{ a: { b: "C" } }> === { a: { b: "C" }, "a.b": "C" } */ export type PathEntries<TResultItem> = { [P in Path<TResultItem>]: PathValue<TResultItem, P>; }; type IsAny<T> = unknown extends T ? [keyof T] extends [never] ? false : true : false; type PathImpl<T, Key extends keyof T> = Key extends string ? IsAny<T[Key]> extends true ? never : T[Key] extends Record<string, any> ? `${Key}.${PathImpl<T[Key], Exclude<keyof T[Key], keyof any[]>> & string}` | `${Key}.${Exclude<keyof T[Key], keyof any[]> & string}` : never : never; type PathImpl2<T> = PathImpl<T, keyof T> | keyof T; export {};