UNPKG

3 kBTypeScriptView Raw
1import { Builtin } from "../built-in";
2import { IsAny } from "../is-any";
3import { IsNever } from "../is-never";
4import { CreateTypeOptions } from "../create-type-options";
5import { ValueOf } from "../value-of";
6type Pathable = string | number;
7type NonRecursiveType = Builtin | Promise<unknown> | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>;
8type DefaultRecursivePathsOptions = {
9 depth: [];
10};
11/**
12 * @param depth This option counts the number of recursive calls in
13 * `RecursivePathsOptions['depth']['length']`. Used in combination with
14 * `PathsOptions['depth']`
15 */
16type RecursivePathsOptions = {
17 depth: any[];
18};
19/**
20 * @param depth By default, the depth option is set to 7. It should cover the
21 * majority of use cases. If by any chance it doesn't fit you, feel free to
22 * increase the value. However, this may increase the chance of getting
23 * `Type instantiation is excessively deep and possibly infinite` error.
24 *
25 * @param anyArrayIndexAccessor By default there is no wildcard access to
26 * array indices - usage must be intentionally configured.
27 */
28type DefaultPathsOptions = {
29 depth: 7;
30 anyArrayIndexAccessor: `${number}`;
31};
32/**
33 * @param depth This option restricts the depth of the paths lookup and removes `Type
34 * instantiation is excessively deep and possibly infinite` errors for
35 * potentially infinite types.
36 *
37 * @param anyArrayIndexAccessor This wildcard will satisfy any array index if defined.
38 */
39type PathsOptions = {
40 depth: number;
41 anyArrayIndexAccessor: string;
42};
43type Append<Tuple extends any[]> = [...Tuple, 0];
44type RecursivePaths<Type, UserOptions extends Required<PathsOptions>, CallOptions extends RecursivePathsOptions> = IsNever<keyof Type> extends true ? never : NonNullable<ValueOf<{
45 [Key in keyof Type]: Key extends Pathable ? `${AnyArrayIndexAccessorOrKey<Key, UserOptions>}` | (CallOptions["depth"]["length"] extends UserOptions["depth"] ? never : Type[Key] extends infer Value ? Value extends Value ? HasParsablePath<Value> extends true ? RecursivePaths<Value, UserOptions, {
46 depth: Append<CallOptions["depth"]>;
47 }> extends infer Rest ? IsNever<Rest> extends true ? never : Rest extends Pathable ? `${AnyArrayIndexAccessorOrKey<Key, UserOptions>}.${Rest}` : never : never : never : never : never) : never;
48}>>;
49type HasParsablePath<Type> = Type extends NonRecursiveType ? false : IsAny<Type> extends true ? false : Type extends object ? true : false;
50type UnsafePaths<Type, Options extends Required<PathsOptions>> = Type extends Type ? HasParsablePath<Type> extends true ? RecursivePaths<Type, Options, DefaultRecursivePathsOptions> : never : never;
51type AnyArrayIndexAccessorOrKey<Key extends Pathable, UserOptions extends Required<PathsOptions>> = Key extends number ? Key | UserOptions["anyArrayIndexAccessor"] : Key;
52export type Paths<Type, OverridePathOptions extends Partial<PathsOptions> = {}> = UnsafePaths<Type, CreateTypeOptions<PathsOptions, OverridePathOptions, DefaultPathsOptions>>;
53export {};