/** * Gets any path of a given Values object. Given: * * `Values = { name: { first: string } }`, * * `PathOf = "name" | "name.first"` */ export declare type PathOf = object extends Values ? any : FlattenPathTuples> & string; /** * Gets the Value at a nested Path. Given: * * `Values = { name: { first: string } }`, * * `ValueMatchingPath = string` */ export declare type ValueMatchingPath> = string extends Path ? any : object extends Values ? any : Values extends readonly (infer SingleValue)[] ? Path extends `${number}.${infer NextPath}` ? NextPath extends PathOf ? ValueMatchingPath : never : SingleValue : Path extends keyof Values ? Values[Path] : Path extends `${infer Key}.${infer NextPath}` ? Key extends keyof Values ? NextPath extends PathOf ? ValueMatchingPath : never : never : never; /** * Gets PathOf which match the requested type. Given: * * `Values = { name: { first: string, last: string } }`, * * `PathMatchingValue = "name.first" | "name.last"` */ export declare type PathMatchingValue = object extends Values ? any : StringOnlyPathOf extends (infer Path) ? Path extends StringOnlyPathOf ? ValueMatchingPath extends Value ? RenumerateTemplate & PathOf : never : never : never; /** * Gets PathOf which extend the requested type. Allows assigning narrower values to wider types. * Useful for `setFieldValue("numberOrStringPath", myNumber)`. Given: * * `Values = { name: string, age: number | string, friendCount: number }`, * * `PathLikeValue = "age" | "friendCount"` */ export declare type PathLikeValue = object extends Values ? any : StringOnlyPathOf extends (infer Path) ? Path extends StringOnlyPathOf ? Value extends ValueMatchingPath ? RenumerateTemplate & PathOf : never : never : never; /** * Recursively convert objects to tuples, like: * * `{ name: { first: string } }` -> `['name'] | ['name', 'first']` */ declare type RecursivelyTuplePaths = Values extends (infer SingleValue)[] ? ["0"] | ["0", ...RecursivelyTuplePaths] | [number] | [number, ...RecursivelyTuplePaths] : Values extends Record ? [keyof Values] | { [Key in keyof Values]: [Key, ...RecursivelyTuplePaths]; }[Extract] : []; /** * Flatten tuples created by RecursivelyTupleKeys into a union of paths, like: * * `['name'] | ['name', 'first' ] -> 'name' | 'name.first'` */ declare type FlattenPathTuples = PathTuples extends [] ? never : PathTuples extends [infer SinglePath] ? SinglePath extends ValidSubtypes ? `${SinglePath}` : never : PathTuples extends [infer Prefix, ...infer Rest] ? Prefix extends ValidSubtypes ? `${Prefix}.${FlattenPathTuples>}` : never : string; /** * Get Paths of a given `Values` WITHOUT template literals like `path.${number}` * * @see https://github.com/microsoft/TypeScript/issues/43907 */ declare type StringOnlyPathOf = object extends Values ? any : FlattenPathTuples, string> & PathOf; /** * Replace `StringOnlyPathOf` with template literals where necessary. * * We can remove this when the PR listed below lands. * * @see https://github.com/microsoft/TypeScript/issues/43907 */ declare type RenumerateTemplate = string extends Path ? any : Path extends `0.${infer NextPath}` ? `${number}.${RenumerateTemplate}` : Path extends `${infer Prefix}.${infer NextPath}` ? `${Prefix}.${RenumerateTemplate}` : Path extends `0` ? `${number}` : Path; export {};