@kakasoo/deep-strict-types
Version:
typescript utility types including deep-strict-omit and pick type
46 lines • 3.53 kB
TypeScript
import { DeepStrictUnbrand } from './DeepStrictUnbrand';
import { Equal } from './Equal';
import type { IsAny } from './IsAny';
import type { IsUnion } from './IsUnion';
import type { ValueType } from './ValueType';
declare namespace DeepStrictObjectKeys {
/**
* Internal helper type that recursively extracts all keys from nested objects
* @template Target - The object type to extract keys from
* @template Joiner - Defines the symbols used to join nested paths (array: '[*]', object: '.')
* @template IsSafe - Controls whether to explore union types that mix primitives and objects
* @template P - The current property keys being processed (excludes array methods)
*/
type Infer<Target extends object, Joiner extends {
array: string;
object: string;
} = {
array: '[*]';
object: '.';
}, IsSafe extends boolean = true, P extends keyof Target = Exclude<keyof Target, keyof []>> = [Target] extends [never] ? never : P extends string ? IsUnion<Target[P]> extends true ? Equal<IsSafe, true> extends true ? P : P | (Target[P] extends infer E ? E extends ValueType ? P : E extends object ? E extends Array<infer _Element extends object> ? P | `${P}${Joiner['array']}${Joiner['object']}${Infer<_Element, Joiner, IsSafe>}` : `${P}${Joiner['object']}${Infer<E, Joiner, IsSafe>}` : never : never) : Target[P] extends Array<infer Element extends object> ? P | `${P}${Joiner['array']}${Joiner['object']}${Infer<Element, Joiner, false>}` : Target[P] extends Array<infer _Element> ? Equal<IsSafe, true> extends true ? P : P | never : Target[P] extends ValueType ? P : IsAny<Target[P]> extends true ? P : Target[P] extends object ? Target[P] extends Record<string, never> ? `${P}` : `${P}` | `${P}${Joiner['object']}${Infer<Target[P], Joiner, false>}` : never : never;
}
/**
* @title Type for Listing All Keys of Nested Objects or Arrays.
*
* A type that extracts all keys of a nested object. If the object contains nested properties,
* the keys are represented using dot notation. For arrays, the keys are represented using
* the `[*]` symbol.
*
* ```ts
* type Example1 = DeepStrictObjectKeys<{ a: { b: 1; c: 2 } }>; // "a" | "a.b" | "a.c"
* type Example2 = DeepStrictObjectKeys<{ a: { b: 1; c: { d: number }[] } }>; // "a" | "a.b" | "a.c" | "a.c[*].d"
* ```
* @template Target Destination type for which you want to pull a key
* @template Joiner It means what symbol to connect when recursively spinning superimposed types.
* @template IsSafe When a key is a combination type of a primitive type and an object, it means whether to perform a recursive search or not.
*/
export type DeepStrictObjectKeys<Target extends object, Joiner extends {
array: string;
object: string;
} = {
array: '[*]';
object: '.';
}, IsSafe extends boolean = true> = DeepStrictUnbrand<Target> extends Array<infer Element> ? IsAny<Element> extends true ? Joiner['array'] : Element extends object ? // For arrays of objects, return both the array key and nested object keys
Joiner['array'] | `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}` : Joiner['array'] : DeepStrictUnbrand<Target> extends readonly (infer Element)[] ? IsAny<Element> extends true ? Joiner['array'] : Element extends object ? Joiner['array'] | `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}` : Joiner['array'] : DeepStrictObjectKeys.Infer<DeepStrictUnbrand<Target>, Joiner, IsSafe>;
export {};
//# sourceMappingURL=DeepStrictObjectKeys.d.ts.map