1 | import {Primitive} from './basic';
|
---|
2 |
|
---|
3 | /**
|
---|
4 | Create a type from another type with all keys and nested keys set to optional.
|
---|
5 |
|
---|
6 | Use-cases:
|
---|
7 | - Merging a default settings/config object with another object, the second object would be a deep partial of the default object.
|
---|
8 | - Mocking and testing complex entities, where populating an entire object with its keys would be redundant in terms of the mock or test.
|
---|
9 |
|
---|
10 | @example
|
---|
11 | ```
|
---|
12 | import {PartialDeep} from 'type-fest';
|
---|
13 |
|
---|
14 | const settings: Settings = {
|
---|
15 | textEditor: {
|
---|
16 | fontSize: 14;
|
---|
17 | fontColor: '#000000';
|
---|
18 | fontWeight: 400;
|
---|
19 | }
|
---|
20 | autocomplete: false;
|
---|
21 | autosave: true;
|
---|
22 | };
|
---|
23 |
|
---|
24 | const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {
|
---|
25 | return {...settings, ...savedSettings};
|
---|
26 | }
|
---|
27 |
|
---|
28 | settings = applySavedSettings({textEditor: {fontWeight: 500}});
|
---|
29 | ```
|
---|
30 | */
|
---|
31 | export type PartialDeep<T> = T extends Primitive
|
---|
32 | ? Partial<T>
|
---|
33 | : T extends Map<infer KeyType, infer ValueType>
|
---|
34 | ? PartialMapDeep<KeyType, ValueType>
|
---|
35 | : T extends Set<infer ItemType>
|
---|
36 | ? PartialSetDeep<ItemType>
|
---|
37 | : T extends ReadonlyMap<infer KeyType, infer ValueType>
|
---|
38 | ? PartialReadonlyMapDeep<KeyType, ValueType>
|
---|
39 | : T extends ReadonlySet<infer ItemType>
|
---|
40 | ? PartialReadonlySetDeep<ItemType>
|
---|
41 | : T extends ((...arguments: any[]) => unknown)
|
---|
42 | ? T | undefined
|
---|
43 | : T extends object
|
---|
44 | ? PartialObjectDeep<T>
|
---|
45 | : unknown;
|
---|
46 |
|
---|
47 | /**
|
---|
48 | Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
|
---|
49 | */
|
---|
50 | interface PartialMapDeep<KeyType, ValueType> extends Map<PartialDeep<KeyType>, PartialDeep<ValueType>> {}
|
---|
51 |
|
---|
52 | /**
|
---|
53 | Same as `PartialDeep`, but accepts only `Set`s as inputs. Internal helper for `PartialDeep`.
|
---|
54 | */
|
---|
55 | interface PartialSetDeep<T> extends Set<PartialDeep<T>> {}
|
---|
56 |
|
---|
57 | /**
|
---|
58 | Same as `PartialDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `PartialDeep`.
|
---|
59 | */
|
---|
60 | interface PartialReadonlyMapDeep<KeyType, ValueType> extends ReadonlyMap<PartialDeep<KeyType>, PartialDeep<ValueType>> {}
|
---|
61 |
|
---|
62 | /**
|
---|
63 | Same as `PartialDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `PartialDeep`.
|
---|
64 | */
|
---|
65 | interface PartialReadonlySetDeep<T> extends ReadonlySet<PartialDeep<T>> {}
|
---|
66 |
|
---|
67 | /**
|
---|
68 | Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
|
---|
69 | */
|
---|
70 | type PartialObjectDeep<ObjectType extends object> = {
|
---|
71 | [KeyType in keyof ObjectType]?: PartialDeep<ObjectType[KeyType]>
|
---|
72 | };
|
---|