import { IfNoDeepValue } from './helpers.js'; import { Or } from './logical.js'; import { IfEquals, IfNever, IfTuple } from './type-check.js'; /** * Marks given keys as required */ export type RequiredSome = Required> & Omit; /** * Make all properties in T required deeply */ export type DeepRequired = { [ K in keyof T as IfNever, never, K> ]-?: IfNoDeepValue> extends true // Do not deep process No-Deep values ? Exclude : // Deep process objects (Exclude, not NonNullable - preserves a `| null` member) DeepRequired>; }; /** * Make all properties in T required deeply including arrays */ export type DeeperRequired = { [K in keyof T as IfNever, never, K>]-?: IfTuple< NonNullable > extends true // Deep process tuples positionally ? DeeperRequiredTuple> : NonNullable extends readonly (infer U)[] // Deep process arrays ? NonNullable extends any[] ? // was mutable - DeeperRequired doesn't touch mutability null extends T[K] ? DeeperRequired[] | null : DeeperRequired[] : null extends T[K] // was readonly - preserve that ? readonly DeeperRequired[] | null : readonly DeeperRequired[] : // Do not deep process No-Deep values IfNoDeepValue> extends true ? Exclude : // Deep process objects (Exclude, not NonNullable - preserves a `| null` member) DeeperRequired>; }; type DeeperRequiredTuple = T extends readonly [infer Head, ...infer Rest] ? [ IfNoDeepValue> extends true ? Exclude : DeeperRequired>, ...DeeperRequiredTuple, ] : []; /** * RequiredKeys * @desc Returns required keys of an object */ export type RequiredKeys = keyof PickRequired; /** * Pick all required properties in T */ export type PickRequired = { [ K in keyof T as Or< // Omit never keys IfNever>, // Omit optional IfEquals<{ [Q in K]: T[K] }, { [Q in K]?: T[K] }> > extends true ? never : K ]: T[K]; }; /** * Pick all required properties in T */ export type OmitRequired = { [ K in keyof T as Or< // Omit never keys IfNever>, // Omit optional IfEquals<{ [Q in K]: T[K] }, { [Q in K]?: T[K] }, false, true> > extends true ? never : K ]: T[K]; }; /** * Pick all required properties in T deeply */ export type DeepPickRequired = { [ K in keyof T as Or< // Omit never keys IfNever>, // Omit optional IfEquals<{ [Q in K]: T[K] }, { [Q in K]?: T[K] }> > extends true ? never : K ]: IfNoDeepValue> extends true // Do not deep process No-Deep values ? T[K] : // Deep process objects (Exclude, not NonNullable - preserves a `| null` member) DeepPickRequired>; }; /** * Omit all required properties in T deeply */ export type DeepOmitRequired = { [ K in keyof T as Or< // Omit never keys IfNever>, // Omit required IfEquals<{ [Q in K]: T[K] }, { [Q in K]-?: T[K] }> > extends true ? never : K ]?: IfNoDeepValue> extends true // Do not deep process No-Deep values ? T[K] : // Deep process objects (Exclude, not NonNullable - preserves a `| null` member) DeepOmitRequired>; }; /** * Pick all required properties in T deeply including arrays */ export type DeeperPickRequired = { [ K in keyof T as Or< // Omit never keys IfNever>, // Omit required IfEquals<{ [Q in K]: T[K] }, { [Q in K]?: T[K] }> > extends true ? never : K ]: IfTuple> extends true // Deep process tuples positionally ? DeeperPickRequiredTuple> : NonNullable extends readonly (infer U)[] // Deep process arrays ? NonNullable extends any[] ? // was mutable - DeeperPickRequired doesn't touch mutability null extends T[K] ? DeeperPickRequired[] | null : DeeperPickRequired[] : null extends T[K] // was readonly - preserve that ? readonly DeeperPickRequired[] | null : readonly DeeperPickRequired[] : // Do not deep process No-Deep values IfNoDeepValue> extends true ? T[K] : // Deep process objects (Exclude, not NonNullable - preserves a `| null` member) DeeperPickRequired>; }; type DeeperPickRequiredTuple = T extends readonly [infer Head, ...infer Rest] ? [ IfNoDeepValue> extends true ? Head : DeeperPickRequired>, ...DeeperPickRequiredTuple, ] : []; /** * Omit all required properties in T deeply including arrays */ export type DeeperOmitRequired = { [ K in keyof T as Or< // Omit never keys IfNever>, // Omit required IfEquals<{ [Q in K]: T[K] }, { [Q in K]-?: T[K] }> > extends true ? never : K ]: IfTuple> extends true // Deep process tuples positionally ? DeeperOmitRequiredTuple> : NonNullable extends readonly (infer U)[] // Deep process arrays ? NonNullable extends any[] ? // was mutable - DeeperOmitRequired doesn't touch mutability null extends T[K] ? DeeperOmitRequired[] | null : DeeperOmitRequired[] : null extends T[K] // was readonly - preserve that ? readonly DeeperOmitRequired[] | null : readonly DeeperOmitRequired[] : // Do not deep process No-Deep values IfNoDeepValue> extends true ? T[K] : // Deep process objects (Exclude, not NonNullable - preserves a `| null` member) DeeperOmitRequired>; }; type DeeperOmitRequiredTuple = T extends readonly [infer Head, ...infer Rest] ? [ IfNoDeepValue> extends true ? Head : DeeperOmitRequired>, ...DeeperOmitRequiredTuple, ] : [];