import { type Primitive } from './Primitive.js'; /** * Same as built-in `Partial`, but works recursively. Useful when 1) you have a config object to which you need to merge another object, which would be a deep partial of a default object, or 2) you need to test or mock complex object, but most of its keys would be redundant for this purpose. * * ```TypeScript * import { DeepPartial } from '@ori/ts-utils'; * import { UiSettings } from './UiSettings'; * * let settings: UiSettings = { * lineNumbers: true, * scrollbar: { * useShadows: false, * vertical: 'visible', * horizontal: 'auto', * }, * minimap: { * enabled: false, * }, * folding: { * enabled: true, * }, * }; * * function updateSettings(newSettings: DeepPartial) { * return { ...settings, ...newSettings }; * } * * settings = updateSettings({ minimap: { enabled: true } }); * ``` * * @typeParam T Base for the new type */ export type DeepPartial = T extends Date | Primitive | RegExp ? T : T extends Map ? DeepPartialMap : T extends Set ? DeepPartialSet : T extends ReadonlyMap ? DeepPartialReadonlyMap : T extends ReadonlySet ? DeepPartialReadonlySet : T extends (...args: any[]) => unknown ? T | undefined : T extends object ? T extends (Array) ? I[] extends (T) ? Array> : DeepPartialObject : DeepPartialObject : unknown; /** * Helper type for {@link DeepPartial}. */ interface DeepPartialMap extends Map, DeepPartial> { } /** * Helper type for {@link DeepPartial}. */ interface DeepPartialSet extends Set> { } /** * Helper type for {@link DeepPartial}. */ interface DeepPartialReadonlyMap extends ReadonlyMap, DeepPartial> { } /** * Helper type for {@link DeepPartial}. */ interface DeepPartialReadonlySet extends ReadonlySet> { } /** * Helper type for {@link DeepPartial}. */ type DeepPartialObject = { [KeyType in keyof ObjectType]?: DeepPartial; }; export {};