Skip to content

DeepPartial

Recursively makes all properties of T optional, including nested objects and array elements.

Available since v2.0.2

import type { DeepPartial } from '@helpers4/type';
type DeepPartial<T> =
  // Mutable array branch must come first: string[] satisfies both (infer U)[] and
  // readonly (infer U)[]. Without this order, mutable arrays would resolve to readonly.
  T extends (infer U)[]
    ? number extends T['length'] ? DeepPartial<U>[] : { [K in keyof T]?: DeepPartial<T[K]> }
    : T extends readonly (infer U)[]
      ? number extends T['length'] ? readonly DeepPartial<U>[] : { readonly [K in keyof T]?: DeepPartial<T[K]> }
      : T extends (...args: never[]) => unknown
        ? T
        : T extends Date | Map<unknown, unknown> | Set<unknown> | Promise<unknown> | RegExp
          ? T
          : T extends object
            ? { [K in keyof T]?: DeepPartial<T[K]> }
            : T
type Config = { server: { host: string; port: number }; debug: boolean };
type PartialConfig = DeepPartial<Config>;
// => { server?: { host?: string; port?: number }; debug?: boolean }

View source on GitHub