UNPKG

5.55 kBTypeScriptView Raw
1import { FieldValues } from '../fields';
2import { BrowserNativeObject, IsAny, IsEqual, Primitive } from '../utils';
3import { ArrayKey, IsTuple, TupleKeys } from './common';
4/**
5 * Helper function to break apart T1 and check if any are equal to T2
6 *
7 * See {@link IsEqual}
8 */
9type AnyIsEqual<T1, T2> = T1 extends T2 ? IsEqual<T1, T2> extends true ? true : never : never;
10/**
11 * Helper type for recursively constructing paths through a type.
12 * This actually constructs the strings and recurses into nested
13 * object types.
14 *
15 * See {@link Path}
16 */
17type PathImpl<K extends string | number, V, TraversedTypes> = V extends Primitive | BrowserNativeObject ? `${K}` : true extends AnyIsEqual<TraversedTypes, V> ? `${K}` : `${K}` | `${K}.${PathInternal<V, TraversedTypes | V>}`;
18/**
19 * Helper type for recursively constructing paths through a type.
20 * This obscures the internal type param TraversedTypes from exported contract.
21 *
22 * See {@link Path}
23 */
24type PathInternal<T, TraversedTypes = T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true ? {
25 [K in TupleKeys<T>]-?: PathImpl<K & string, T[K], TraversedTypes>;
26}[TupleKeys<T>] : PathImpl<ArrayKey, V, TraversedTypes> : {
27 [K in keyof T]-?: PathImpl<K & string, T[K], TraversedTypes>;
28}[keyof T];
29/**
30 * Type which eagerly collects all paths through a type
31 * @typeParam T - type which should be introspected
32 * @example
33 * ```
34 * Path<{foo: {bar: string}}> = 'foo' | 'foo.bar'
35 * ```
36 */
37export type Path<T> = T extends any ? PathInternal<T> : never;
38/**
39 * See {@link Path}
40 */
41export type FieldPath<TFieldValues extends FieldValues> = Path<TFieldValues>;
42/**
43 * Helper type for recursively constructing paths through a type.
44 * This actually constructs the strings and recurses into nested
45 * object types.
46 *
47 * See {@link ArrayPath}
48 */
49type ArrayPathImpl<K extends string | number, V, TraversedTypes> = V extends Primitive | BrowserNativeObject ? IsAny<V> extends true ? string : never : V extends ReadonlyArray<infer U> ? U extends Primitive | BrowserNativeObject ? IsAny<V> extends true ? string : never : true extends AnyIsEqual<TraversedTypes, V> ? never : `${K}` | `${K}.${ArrayPathInternal<V, TraversedTypes | V>}` : true extends AnyIsEqual<TraversedTypes, V> ? never : `${K}.${ArrayPathInternal<V, TraversedTypes | V>}`;
50/**
51 * Helper type for recursively constructing paths through a type.
52 * This obscures the internal type param TraversedTypes from exported contract.
53 *
54 * See {@link ArrayPath}
55 */
56type ArrayPathInternal<T, TraversedTypes = T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true ? {
57 [K in TupleKeys<T>]-?: ArrayPathImpl<K & string, T[K], TraversedTypes>;
58}[TupleKeys<T>] : ArrayPathImpl<ArrayKey, V, TraversedTypes> : {
59 [K in keyof T]-?: ArrayPathImpl<K & string, T[K], TraversedTypes>;
60}[keyof T];
61/**
62 * Type which eagerly collects all paths through a type which point to an array
63 * type.
64 * @typeParam T - type which should be introspected.
65 * @example
66 * ```
67 * Path<{foo: {bar: string[], baz: number[]}}> = 'foo.bar' | 'foo.baz'
68 * ```
69 */
70export type ArrayPath<T> = T extends any ? ArrayPathInternal<T> : never;
71/**
72 * See {@link ArrayPath}
73 */
74export type FieldArrayPath<TFieldValues extends FieldValues> = ArrayPath<TFieldValues>;
75/**
76 * Type to evaluate the type which the given path points to.
77 * @typeParam T - deeply nested type which is indexed by the path
78 * @typeParam P - path into the deeply nested type
79 * @example
80 * ```
81 * PathValue<{foo: {bar: string}}, 'foo.bar'> = string
82 * PathValue<[number, string], '1'> = string
83 * ```
84 */
85export type PathValue<T, P extends Path<T> | ArrayPath<T>> = T extends any ? P extends `${infer K}.${infer R}` ? K extends keyof T ? R extends Path<T[K]> ? PathValue<T[K], R> : never : K extends `${ArrayKey}` ? T extends ReadonlyArray<infer V> ? PathValue<V, R & Path<V>> : never : never : P extends keyof T ? T[P] : P extends `${ArrayKey}` ? T extends ReadonlyArray<infer V> ? V : never : never : never;
86/**
87 * See {@link PathValue}
88 */
89export type FieldPathValue<TFieldValues extends FieldValues, TFieldPath extends FieldPath<TFieldValues>> = PathValue<TFieldValues, TFieldPath>;
90/**
91 * See {@link PathValue}
92 */
93export type FieldArrayPathValue<TFieldValues extends FieldValues, TFieldArrayPath extends FieldArrayPath<TFieldValues>> = PathValue<TFieldValues, TFieldArrayPath>;
94/**
95 * Type to evaluate the type which the given paths point to.
96 * @typeParam TFieldValues - field values which are indexed by the paths
97 * @typeParam TPath - paths into the deeply nested field values
98 * @example
99 * ```
100 * FieldPathValues<{foo: {bar: string}}, ['foo', 'foo.bar']>
101 * = [{bar: string}, string]
102 * ```
103 */
104export type FieldPathValues<TFieldValues extends FieldValues, TPath extends FieldPath<TFieldValues>[] | readonly FieldPath<TFieldValues>[]> = {} & {
105 [K in keyof TPath]: FieldPathValue<TFieldValues, TPath[K] & FieldPath<TFieldValues>>;
106};
107/**
108 * Type which eagerly collects all paths through a fieldType that matches a give type
109 * @typeParam TFieldValues - field values which are indexed by the paths
110 * @typeParam TValue - the value you want to match into each type
111 * @example
112 * ```typescript
113 * FieldPathByValue<{foo: {bar: number}, baz: number, bar: string}, number>
114 * = 'foo.bar' | 'baz'
115 * ```
116 */
117export type FieldPathByValue<TFieldValues extends FieldValues, TValue> = {
118 [Key in FieldPath<TFieldValues>]: FieldPathValue<TFieldValues, Key> extends TValue ? Key : never;
119}[FieldPath<TFieldValues>];
120export {};
121//# sourceMappingURL=eager.d.ts.map
\No newline at end of file