/** * Recursion depth counter to prevent TypeScript depth limit errors. * Maps depth D to D-1, terminating at 0. */ type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; /** * Generates a union of all valid dot-notation paths for type T. * Recursively enumerates all property access chains up to depth D. * Depth of 8 supports paths like 'format.style.theme.common.axes.number.crosshair'. * * Arrays are flattened into their element type (like JSON Schema's `items`). * For example, `{ style: Array<{ stroke: string }> }` yields paths 'style' | 'style.stroke'. * * @example * ```ts * type Widget = { format: { title: { text: string; enabled: boolean } } }; * type Paths = Path; * // = 'format' | 'format.title' | 'format.title.text' | 'format.title.enabled' * * type WithArray = { items: Array<{ name: string }> }; * type ArrayPaths = Path; * // = 'items' | 'items.name' * ``` */ export type AgPath = [D] extends [0] ? never : T extends Array ? AgPath, Prev[D]> : T extends object ? { [K in keyof T & string]: K | `${K}.${AgPath, Prev[D]>}`; }[keyof T & string] : never; export {};