forked from sindresorhus/type-fest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
writable-deep.d.ts
64 lines (54 loc) · 2.5 KB
/
writable-deep.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import type {BuiltIns, HasMultipleCallSignatures} from './internal';
import type {Writable} from './writable.js';
/**
Create a deeply mutable version of an `object`/`ReadonlyMap`/`ReadonlySet`/`ReadonlyArray` type. The inverse of `ReadonlyDeep<T>`. Use `Writable<T>` if you only need one level deep.
This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509), or to define a single model where the only thing that changes is whether or not some of the keys are writable.
@example
```
import type {WritableDeep} from 'type-fest';
type Foo = {
readonly a: number;
readonly b: readonly string[]; // To show that mutability is deeply affected.
readonly c: boolean;
};
const writableDeepFoo: WritableDeep<Foo> = {a: 1, b: ['2'], c: true};
writableDeepFoo.a = 3;
writableDeepFoo.b[0] = 'new value';
writableDeepFoo.b = ['something'];
```
Note that types containing overloaded functions are not made deeply writable due to a [TypeScript limitation](https://github.com/microsoft/TypeScript/issues/29732).
@see Writable
@category Object
@category Array
@category Set
@category Map
*/
export type WritableDeep<T> = T extends BuiltIns
? T
: T extends (...arguments: any[]) => unknown
? {} extends WritableObjectDeep<T>
? T
: HasMultipleCallSignatures<T> extends true
? T
: ((...arguments: Parameters<T>) => ReturnType<T>) & WritableObjectDeep<T>
: T extends Readonly<ReadonlyMap<infer KeyType, infer ValueType>>
? WritableMapDeep<KeyType, ValueType>
: T extends Readonly<ReadonlySet<infer ItemType>>
? WritableSetDeep<ItemType>
: T extends object
? WritableObjectDeep<T>
: unknown;
/**
Same as `WritableDeep`, but accepts only `Map`s as inputs. Internal helper for `WritableDeep`.
*/
type WritableMapDeep<KeyType, ValueType> = {} & Writable<Map<WritableDeep<KeyType>, WritableDeep<ValueType>>>;
/**
Same as `WritableDeep`, but accepts only `Set`s as inputs. Internal helper for `WritableDeep`.
*/
type WritableSetDeep<ItemType> = {} & Writable<Set<WritableDeep<ItemType>>>;
/**
Same as `WritableDeep`, but accepts only `object`s as inputs. Internal helper for `WritableDeep`.
*/
type WritableObjectDeep<ObjectType extends object> = {
-readonly [KeyType in keyof ObjectType]: WritableDeep<ObjectType[KeyType]>
};