DeepPartial type
Makes every property optional, at every depth: a patch of a nested settings object, read-only since a patch is only read. Functions are kept whole; array items are deeply partial.
ts
import type { DeepPartial } from 'utils';Signature
ts
export type DeepPartial<T> = T extends (...arguments_: readonly never[]) => unknown
? T
: T extends readonly (infer Item)[]
? readonly DeepPartial<Item>[]
: T extends object
? { readonly [K in keyof T]?: DeepPartial<T[K]> }
: T;Parameters
| Name | Description |
|---|---|
T | The type to loosen. |
Example
ts
type SettingsPatch = DeepPartial<Settings>;
const patch: SettingsPatch = { chart: { grid: { isVisible: false } } };Tests
Line coverage: 0 %.
- ✅ makes every depth optional
- ✅ keeps functions whole
Source
src/types/deep-partial.ts (on GitHub)
Used by
deepMerge: Applies a partial patch to nested settings, such as saved preferences over the defaults: plain objects are merged at every depth, other values replace,undefinedkeeps.
Source code
ts
/**
* Makes every property optional, at every depth: a patch of a nested settings object, read-only since a
* patch is only read. Functions are kept whole; array items are deeply partial.
*
* @template T - The type to loosen.
* @example
* type SettingsPatch = DeepPartial<Settings>;
* const patch: SettingsPatch = { chart: { grid: { isVisible: false } } };
*/
export type DeepPartial<T> = T extends (...arguments_: readonly never[]) => unknown
? T
: T extends readonly (infer Item)[]
? readonly DeepPartial<Item>[]
: T extends object
? { readonly [K in keyof T]?: DeepPartial<T[K]> }
: T;Test file
ts
import type { DeepPartial } from './deep-partial';
interface Settings {
readonly chart: { readonly grid: { readonly step: number }; readonly series: { readonly id: string }[] };
format(value: number): string;
}
describe('DeepPartial', () => {
it('makes every depth optional', () => {
expectTypeOf<Omit<DeepPartial<Settings>, 'format'>>().toEqualTypeOf<{
readonly chart?: {
readonly grid?: { readonly step?: number };
readonly series?: readonly { readonly id?: string }[];
};
}>();
});
it('keeps functions whole', () => {
expectTypeOf<DeepPartial<Settings>['format']>().toEqualTypeOf<((value: number) => string) | undefined>();
});
});Keywords: deep, partial, types, type