@mantine/form
Version:
Mantine form management library
25 lines (24 loc) • 2.32 kB
TypeScript
type Primitive = null | undefined | string | number | boolean | symbol | bigint;
type ArrayKey = number;
type IsTuple<T extends readonly any[]> = number extends T['length'] ? false : true;
type TupleKeys<T extends readonly any[]> = Exclude<keyof T, keyof any[]>;
type Prev = [never, 0, 1, 2, 3, 4, 5];
type Depth = 5;
type PathConcat<TKey extends string | number, TValue, D extends number> = TValue extends Primitive ? `${TKey}` : `${TKey}` | `${TKey}.${Path<TValue, Prev[D]>}`;
export type Path<T, D extends number = Depth> = [D] extends [never] ? never : T extends readonly (infer V)[] ? IsTuple<T> extends true ? {
[K in TupleKeys<T>]-?: PathConcat<K & string, T[K], D>;
}[TupleKeys<T>] : PathConcat<ArrayKey, V, D> : {
[K in keyof T]-?: PathConcat<K & string, T[K], D>;
}[keyof T];
type ArrayPathConcat<TKey extends string | number, TValue, D extends number> = [D] extends [never] ? never : TValue extends Primitive ? never : TValue extends readonly (infer U)[] ? U extends Primitive ? never : `${TKey}` | `${TKey}.${ArrayPath<TValue, Prev[D]>}` : `${TKey}.${ArrayPath<TValue, Prev[D]>}`;
export type ArrayPath<T, D extends number = Depth> = [D] extends [never] ? never : T extends readonly (infer V)[] ? IsTuple<T> extends true ? {
[K in TupleKeys<T>]-?: ArrayPathConcat<K & string, T[K], D>;
}[TupleKeys<T>] : ArrayPathConcat<ArrayKey, V, D> : {
[K in keyof T]-?: ArrayPathConcat<K & string, T[K], D>;
}[keyof T];
export type PathValue<T, TPath extends string> = T extends any ? TPath extends `${infer K}.${infer R}` ? K extends keyof T ? R extends Path<T[K]> ? undefined extends T[K] ? PathValue<T[K], R> | undefined : PathValue<T[K], R> : never : K extends `${ArrayKey}` ? T extends readonly (infer V)[] ? PathValue<V, R & Path<V>> : never : never : TPath extends keyof T ? T[TPath] : TPath extends `${ArrayKey}` ? T extends readonly (infer V)[] ? V : never : never : never;
export type FormPathValue<T, TPath extends string> = PathValue<T, TPath> extends never ? any : PathValue<T, TPath>;
export type ArrayElement<T> = T extends readonly (infer U)[] ? U : never;
export type FormArrayElement<T, TPath extends string> = ArrayElement<FormPathValue<T, TPath>> extends never ? any : ArrayElement<FormPathValue<T, TPath>>;
export type LooseKeys<T> = Path<T> | ArrayPath<T> | (string & {});
export {};