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