get-nested-object-property
Version:
A safe way to retrieve values from any level of the object cavity
28 lines (27 loc) • 2.2 kB
TypeScript
declare type FieldValues = Record<string, any>;
declare type TupleKeys<T extends ReadonlyArray<any>> = Exclude<keyof T, keyof any[]>;
declare type Primitive = null | undefined | string | number | boolean | symbol | bigint;
declare type IsTuple<T extends ReadonlyArray<any>> = number extends T['length'] ? false : true;
declare type FieldPath<TFieldValues extends FieldValues> = TPath<TFieldValues>;
declare type TPathValue<T, P extends TPath<T> | TArrayPath<T>> = T extends any ? P extends `${infer K}.${infer R}` ? K extends keyof T ? R extends TPath<T[K]> ? TPathValue<T[K], R> : never : K extends `${number}` ? T extends ReadonlyArray<infer V> ? TPathValue<V, R & TPath<V>> : never : never : P extends keyof T ? T[P] : P extends `${number}` ? T extends ReadonlyArray<infer V> ? V : never : never : never;
declare type TArrayPathImpl<K extends string | number, V> = V extends Primitive ? never : V extends ReadonlyArray<infer U> ? U extends Primitive ? never : `${K}` | `${K}.${TArrayPath<V>}` : `${K}.${TArrayPath<V>}`;
declare type TArrayPath<T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true ? {
[K in TupleKeys<T>]-?: TArrayPathImpl<K & string, T[K]>;
}[TupleKeys<T>] : TArrayPathImpl<number, V> : {
[K in keyof T]-?: TArrayPathImpl<K & string, T[K]>;
}[keyof T];
declare type TPathImpl<K extends string | number, V> = V extends Primitive ? `${K}` : `${K}` | `${K}.${TPath<V>}`;
declare const $NestedValue: unique symbol;
declare type TNestedValue<TValue extends object = object> = {
[$NestedValue]: never;
} & TValue;
export declare type TPath<T> = T extends ReadonlyArray<infer V> ? IsTuple<T> extends true ? {
[K in TupleKeys<T>]-?: TPathImpl<K & string, T[K]>;
}[TupleKeys<T>] : TPathImpl<number, V> : {
[K in keyof T]-?: TPathImpl<K & string, T[K]>;
}[keyof T];
export declare type TFieldPathValue<TFieldValues extends FieldValues, TFieldPath extends FieldPath<TFieldValues>> = TPathValue<TFieldValues, TFieldPath>;
export declare type TUnpackNestedValue<T> = T extends TNestedValue<infer U> ? U : T extends Date | FileList | File | Blob ? T : T extends object ? {
[K in keyof T]: TUnpackNestedValue<T[K]>;
} : T;
export {};