es-toolkit
Version:
A state-of-the-art, high-performance JavaScript utility library with a small bundle size and strong type annotations.
21 lines • 1.2 kB
text/typescript
//#region src/types/DeepPartial.d.ts
/**
* Makes all properties of `T` optional recursively, unlike the built-in
* `Partial` which only affects the first level.
*
* Recurses into plain objects, arrays/tuples (elements do not become sparse),
* and `Map`/`Set` contents. Functions, `Date`, and `RegExp` pass through
* unchanged.
*
* @template T - The type to make deeply optional.
*
* @example
* type Config = { server: { host: string; port: number }; debug: boolean };
* type ConfigPatch = DeepPartial<Config>;
* // => { server?: { host?: string; port?: number }; debug?: boolean }
*
* const patch: ConfigPatch = { server: { port: 8080 } }; // ok, host omitted
*/
type DeepPartial<T> = T extends ((...args: any[]) => unknown) | Date | RegExp ? T : T extends Map<infer K, infer V> ? Map<DeepPartial<K>, DeepPartial<V>> : T extends ReadonlyMap<infer K, infer V> ? ReadonlyMap<DeepPartial<K>, DeepPartial<V>> : T extends Set<infer U> ? Set<DeepPartial<U>> : T extends ReadonlySet<infer U> ? ReadonlySet<DeepPartial<U>> : T extends readonly unknown[] ? { [K in keyof T]: DeepPartial<T[K]> } : T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T;
//#endregion
export { DeepPartial };