UNPKG

object-shape-tester

Version:
66 lines (65 loc) 2.71 kB
import { type OptionalKind, type TNull, type TSchema, type TUndefined, type TUnsafe } from '@sinclair/typebox'; import { type IsAny, type OptionalKeysOf, type Primitive, type RequiredKeysOf, type Simplify } from 'type-fest'; import { type Shape, type ShapeInitType } from '../shape/shape.js'; /** * Checks if a type is possibly `undefined` or `null`. `any` is included. * * @category Internal */ export type IsNullable<T> = IsAny<T> extends true ? true : null extends Extract<T, null> ? true : undefined extends Extract<T, undefined> ? true : false; /** * Checks if a schema is possibly `undefined`, `null`, or optional. `any` is included. * * @category Internal */ export type IsNullableSchema<T extends TSchema> = IsNullable<ShapeInitType<T>> extends true ? true : T extends TNull ? true : T extends TUndefined ? true : T[typeof OptionalKind] extends 'Optional' ? true : false; /** * Ensures that any property that is optional, potentially `null` or `undefined` is fully optional, * possibly `null` or `undefined`. * * @category Internal */ export type EnsureNullableType<Original> = Original extends Primitive ? Original : Original extends ReadonlyArray<any> ? { [Key in keyof Original]: EnsureNullableType<Original[Key]>; } : Simplify<{ [Key in RequiredKeysOf<Extract<Original, object>> as IsNullable<Original[Key]> extends true ? never : Key]: EnsureNullableType<Original[Key]>; } & { [Key in OptionalKeysOf<Extract<Original, object>>]?: EnsureNullableType<Original[Key]> | undefined | null; } & { [Key in RequiredKeysOf<Extract<Original, object>> as IsNullable<Original[Key]> extends true ? Key : never]?: EnsureNullableType<Original[Key]> | undefined | null; }>; /** * Creates a shape from an object shape where any property that can be any kind of nullable * (optional, `null`, or `undefined`) can now be _all_ kinds of nullable. That is, any property that * is optional or can be `null` or `undefined` becomes all three. * * @category Shape * @example * * ```ts * import { * nullToNullableShape, * unionShape, * assertValidShape, * defineShape, * } from 'object-shape-tester'; * * const myShape = nullToNullableShape({ * a: '', * b: unionShape(null, -1), * c: null, * d: { * e: unionShape(null, ''), * }, * }); * * // passes * assertValidShape({a: 'hi', b: null, d: {}}, myShape); * assertValidShape({a: 'hi', b: undefined, d: {e: undefined}}, myShape); * * // fails * assertValidShape({b: null}, myShape); * assertValidShape({a: 'hi'}, myShape); * ``` */ export declare function ensureNullableShape<Original>(originalShape: Original): Shape<TUnsafe<EnsureNullableType<ShapeInitType<Original>>>>;