import { IfNoDeepValue } from './helpers.js'; import { IfNever, IfTuple } from './type-check.js'; /** * OmitUndefined is a type that omits all properties with a value of type "undefined". */ export type OmitUndefined = { [K in keyof T as IfNever, never, K>]: T[K]; }; /** * Omit all "never" and "undefined" properties in T deeply */ export type DeepOmitUndefined = { [K in keyof T as IfNever, never, K>]: IfNoDeepValue< // Do not deep process No-Deep values Exclude > extends true ? T[K] : // Deep process objects DeepOmitUndefined>; }; /** * Omit all "never" and "undefined" properties in T deeply including arrays */ export type DeeperOmitUndefined = { [K in keyof T as IfNever, never, K>]: IfTuple< NonNullable > extends true // Deep process tuples positionally ? DeeperOmitUndefinedTuple> : NonNullable extends readonly (infer U)[] // Deep process arrays ? NonNullable extends any[] ? // was mutable - DeeperOmitUndefined doesn't touch mutability null extends T[K] ? DeeperOmitUndefined[] | null : DeeperOmitUndefined[] : null extends T[K] // was readonly - preserve that ? readonly DeeperOmitUndefined[] | null : readonly DeeperOmitUndefined[] : // Do not deep process No-Deep values IfNoDeepValue> extends true ? T[K] : // Deep process objects (Exclude, not NonNullable - preserves a `| null` member) DeeperOmitUndefined>; }; type DeeperOmitUndefinedTuple = T extends readonly [ infer Head, ...infer Rest, ] ? [ IfNoDeepValue> extends true ? Head : DeeperOmitUndefined>, ...DeeperOmitUndefinedTuple, ] : [];