Skip to content

Commit 4928ac5

Browse files
committed
Inline PartialDeep definition from type-fest
1 parent 354b7b1 commit 4928ac5

File tree

1 file changed

+129
-2
lines changed

1 file changed

+129
-2
lines changed

Diff for: packages/bento-design-system/src/util/PartialDeep.ts

+129-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,130 @@
1-
export type PartialDeep<O extends Record<string, unknown>> = {
2-
[K in keyof O]+?: O[K] extends Record<string, unknown> ? PartialDeep<O[K]> : O[K];
1+
// Adapted from https://github.com/sindresorhus/type-fest/blob/2c39d54477584ee8c65d9d22fb0ee7ff69571128/source/partial-deep.d.ts
2+
// License: https://github.com/sindresorhus/type-fest/blob/2c39d54477584ee8c65d9d22fb0ee7ff69571128/license-mit
3+
4+
import { NavigationConfig } from "../Navigation/Config";
5+
6+
export type Primitive = null | undefined | string | number | boolean | symbol | bigint;
7+
8+
export type BuiltIns = Primitive | Date | RegExp;
9+
10+
/**
11+
@see PartialDeep
12+
*/
13+
export type PartialDeepOptions = {
14+
/**
15+
Whether to affect the individual elements of arrays and tuples.
16+
17+
@default false
18+
*/
19+
readonly recurseIntoArrays?: boolean;
320
};
21+
22+
/**
23+
Create a type from another type with all keys and nested keys set to optional.
24+
25+
Use-cases:
26+
- Merging a default settings/config object with another object, the second object would be a deep partial of the default object.
27+
- Mocking and testing complex entities, where populating an entire object with its keys would be redundant in terms of the mock or test.
28+
29+
@example
30+
```
31+
import type {PartialDeep} from 'type-fest';
32+
33+
const settings: Settings = {
34+
textEditor: {
35+
fontSize: 14;
36+
fontColor: '#000000';
37+
fontWeight: 400;
38+
}
39+
autocomplete: false;
40+
autosave: true;
41+
};
42+
43+
const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {
44+
return {...settings, ...savedSettings};
45+
}
46+
47+
settings = applySavedSettings({textEditor: {fontWeight: 500}});
48+
```
49+
50+
By default, this does not affect elements in array and tuple types. You can change this by passing `{recurseIntoArrays: true}` as the second type argument:
51+
52+
```
53+
import type {PartialDeep} from 'type-fest';
54+
55+
interface Settings {
56+
languages: string[];
57+
}
58+
59+
const partialSettings: PartialDeep<Settings, {recurseIntoArrays: true}> = {
60+
languages: [undefined]
61+
};
62+
```
63+
64+
@category Object
65+
@category Array
66+
@category Set
67+
@category Map
68+
*/
69+
export type PartialDeep<T, Options extends PartialDeepOptions = {}> = T extends
70+
| BuiltIns
71+
| ((...arguments_: any[]) => unknown)
72+
| (new (...arguments_: any[]) => unknown)
73+
? T
74+
: T extends Map<infer KeyType, infer ValueType>
75+
? PartialMapDeep<KeyType, ValueType, Options>
76+
: T extends Set<infer ItemType>
77+
? PartialSetDeep<ItemType, Options>
78+
: T extends ReadonlyMap<infer KeyType, infer ValueType>
79+
? PartialReadonlyMapDeep<KeyType, ValueType, Options>
80+
: T extends ReadonlySet<infer ItemType>
81+
? PartialReadonlySetDeep<ItemType, Options>
82+
: T extends object
83+
? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
84+
? Options["recurseIntoArrays"] extends true
85+
? ItemType[] extends T // Test for arrays (non-tuples) specifically
86+
? readonly ItemType[] extends T // Differentiate readonly and mutable arrays
87+
? ReadonlyArray<PartialDeep<ItemType | undefined, Options>>
88+
: Array<PartialDeep<ItemType | undefined, Options>>
89+
: PartialObjectDeep<T, Options> // Tuples behave properly
90+
: T // If they don't opt into array testing, just use the original type
91+
: PartialObjectDeep<T, Options>
92+
: unknown;
93+
94+
/**
95+
Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
96+
*/
97+
type PartialMapDeep<KeyType, ValueType, Options extends PartialDeepOptions> = {} & Map<
98+
PartialDeep<KeyType, Options>,
99+
PartialDeep<ValueType, Options>
100+
>;
101+
102+
/**
103+
Same as `PartialDeep`, but accepts only `Set`s as inputs. Internal helper for `PartialDeep`.
104+
*/
105+
type PartialSetDeep<T, Options extends PartialDeepOptions> = {} & Set<PartialDeep<T, Options>>;
106+
107+
/**
108+
Same as `PartialDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `PartialDeep`.
109+
*/
110+
type PartialReadonlyMapDeep<
111+
KeyType,
112+
ValueType,
113+
Options extends PartialDeepOptions
114+
> = {} & ReadonlyMap<PartialDeep<KeyType, Options>, PartialDeep<ValueType, Options>>;
115+
116+
/**
117+
Same as `PartialDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `PartialDeep`.
118+
*/
119+
type PartialReadonlySetDeep<T, Options extends PartialDeepOptions> = {} & ReadonlySet<
120+
PartialDeep<T, Options>
121+
>;
122+
123+
/**
124+
Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
125+
*/
126+
type PartialObjectDeep<ObjectType extends object, Options extends PartialDeepOptions> = {
127+
[KeyType in keyof ObjectType]?: PartialDeep<ObjectType[KeyType], Options>;
128+
};
129+
130+
export type A = PartialDeep<NavigationConfig>;

0 commit comments

Comments
 (0)