|
| 1 | +/** |
| 2 | + * @private |
| 3 | + */ |
| 4 | +export type UnwrapOneLevelOfArray<T> = T extends (infer U)[] ? U : T; |
| 5 | +type Narrowable = string | number | bigint | boolean; |
| 6 | +type NarrowRaw<A> = (A extends [] ? [] : never) | (A extends Narrowable ? A : never) | { |
| 7 | + [K in keyof A]: A[K] extends Function ? A[K] : NarrowRaw<A[K]>; |
| 8 | +}; |
| 9 | +type Try<A1, A2, Catch = never> = A1 extends A2 ? A1 : Catch; |
| 10 | +/** |
| 11 | + * @private |
| 12 | + */ |
| 13 | +export type Narrow<A> = Try<A, [], NarrowRaw<A>>; |
| 14 | +export interface AnyDeepKeyAndValue { |
| 15 | + key: string; |
| 16 | + value: any; |
| 17 | +} |
| 18 | +export type ArrayAccessor<TParent extends AnyDeepKeyAndValue> = `${TParent['key'] extends never ? '' : TParent['key']}[${number}]`; |
| 19 | +export interface ArrayDeepKeyAndValue<in out TParent extends AnyDeepKeyAndValue, in out T extends ReadonlyArray<any>> extends AnyDeepKeyAndValue { |
| 20 | + key: ArrayAccessor<TParent>; |
| 21 | + value: T[number] | Nullable<TParent['value']>; |
| 22 | +} |
| 23 | +export type DeepKeyAndValueArray<TParent extends AnyDeepKeyAndValue, T extends ReadonlyArray<any>, TAcc> = DeepKeysAndValuesImpl<NonNullable<T[number]>, ArrayDeepKeyAndValue<TParent, T>, TAcc | ArrayDeepKeyAndValue<TParent, T>>; |
| 24 | +export type TupleAccessor<TParent extends AnyDeepKeyAndValue, TKey extends string> = `${TParent['key'] extends never ? '' : TParent['key']}[${TKey}]`; |
| 25 | +export interface TupleDeepKeyAndValue<in out TParent extends AnyDeepKeyAndValue, in out T, in out TKey extends AllTupleKeys<T>> extends AnyDeepKeyAndValue { |
| 26 | + key: TupleAccessor<TParent, TKey>; |
| 27 | + value: T[TKey] | Nullable<TParent['value']>; |
| 28 | +} |
| 29 | +export type AllTupleKeys<T> = T extends any ? keyof T & `${number}` : never; |
| 30 | +export type DeepKeyAndValueTuple<TParent extends AnyDeepKeyAndValue, T extends ReadonlyArray<any>, TAcc, TAllKeys extends AllTupleKeys<T> = AllTupleKeys<T>> = TAllKeys extends any ? DeepKeysAndValuesImpl<NonNullable<T[TAllKeys]>, TupleDeepKeyAndValue<TParent, T, TAllKeys>, TAcc | TupleDeepKeyAndValue<TParent, T, TAllKeys>> : never; |
| 31 | +export type AllObjectKeys<T> = T extends any ? keyof T & (string | number) : never; |
| 32 | +export type ObjectAccessor<TParent extends AnyDeepKeyAndValue, TKey extends string | number> = TParent['key'] extends never ? `${TKey}` : `${TParent['key']}.${TKey}`; |
| 33 | +export type Nullable<T> = T & (undefined | null); |
| 34 | +export type ObjectValue<TParent extends AnyDeepKeyAndValue, T, TKey extends AllObjectKeys<T>> = T[TKey] | Nullable<TParent['value']>; |
| 35 | +export interface ObjectDeepKeyAndValue<in out TParent extends AnyDeepKeyAndValue, in out T, in out TKey extends AllObjectKeys<T>> extends AnyDeepKeyAndValue { |
| 36 | + key: ObjectAccessor<TParent, TKey>; |
| 37 | + value: ObjectValue<TParent, T, TKey>; |
| 38 | +} |
| 39 | +export type DeepKeyAndValueObject<TParent extends AnyDeepKeyAndValue, T, TAcc, TAllKeys extends AllObjectKeys<T> = AllObjectKeys<T>> = TAllKeys extends any ? DeepKeysAndValuesImpl<NonNullable<T[TAllKeys]>, ObjectDeepKeyAndValue<TParent, T, TAllKeys>, TAcc | ObjectDeepKeyAndValue<TParent, T, TAllKeys>> : never; |
| 40 | +export type UnknownAccessor<TParent extends AnyDeepKeyAndValue> = TParent['key'] extends never ? string : `${TParent['key']}.${string}`; |
| 41 | +export interface UnknownDeepKeyAndValue<TParent extends AnyDeepKeyAndValue> extends AnyDeepKeyAndValue { |
| 42 | + key: UnknownAccessor<TParent>; |
| 43 | + value: unknown; |
| 44 | +} |
| 45 | +export type DeepKeysAndValues<T> = DeepKeysAndValuesImpl<T> extends AnyDeepKeyAndValue ? DeepKeysAndValuesImpl<T> : never; |
| 46 | +export type DeepKeysAndValuesImpl<T, TParent extends AnyDeepKeyAndValue = never, TAcc = never> = unknown extends T ? TAcc | UnknownDeepKeyAndValue<TParent> : unknown extends T ? T : T extends string | number | boolean | bigint | Date ? TAcc : T extends ReadonlyArray<any> ? number extends T['length'] ? DeepKeyAndValueArray<TParent, T, TAcc> : DeepKeyAndValueTuple<TParent, T, TAcc> : keyof T extends never ? TAcc | UnknownDeepKeyAndValue<TParent> : T extends object ? DeepKeyAndValueObject<TParent, T, TAcc> : TAcc; |
| 47 | +export type DeepRecord<T> = { |
| 48 | + [TRecord in DeepKeysAndValues<T> as TRecord['key']]: TRecord['value']; |
| 49 | +}; |
| 50 | +/** |
| 51 | + * The keys of an object or array, deeply nested. |
| 52 | + */ |
| 53 | +export type DeepKeys<T> = unknown extends T ? string : DeepKeysAndValues<T>['key']; |
| 54 | +/** |
| 55 | + * Infer the type of a deeply nested property within an object or an array. |
| 56 | + */ |
| 57 | +export type DeepValue<TValue, TAccessor> = unknown extends TValue ? TValue : TAccessor extends DeepKeys<TValue> ? DeepRecord<TValue>[TAccessor] : never; |
| 58 | +export {}; |
0 commit comments