0
# Deep Wrapper Types
1
2
Recursive type transformations that apply operations to nested object structures at any depth. These types work recursively through all levels of object nesting.
3
4
## Capabilities
5
6
### Buildable
7
8
Constructs a type by combining `DeepPartial` and `DeepWritable`, meaning all properties from type `Type` are recursively set as non-`readonly` and optional.
9
10
```typescript { .api }
11
type Buildable<Type> = DeepWritable<DeepPartial<Type>>;
12
```
13
14
**Usage Example:**
15
16
```typescript
17
import type { Buildable } from "ts-essentials";
18
19
type User = {
20
readonly id: number;
21
readonly profile: {
22
readonly name: string;
23
readonly settings: {
24
readonly theme: string;
25
readonly notifications: boolean;
26
};
27
};
28
};
29
30
type UserBuilder = Buildable<User>;
31
// Result: All properties optional and writable recursively
32
// {
33
// id?: number;
34
// profile?: {
35
// name?: string;
36
// settings?: {
37
// theme?: string;
38
// notifications?: boolean;
39
// };
40
// };
41
// }
42
43
const builder: UserBuilder = {}; // Valid - all optional
44
builder.id = 1; // Valid - all writable
45
```
46
47
### DeepMarkOptional
48
49
Constructs a type by picking all properties from type `Type` where properties by paths `KeyPathUnion` are set as optional recursively.
50
51
```typescript { .api }
52
type DeepMarkOptional<Type, KeyPathUnion extends Paths<Type>> = /* complex recursive type */;
53
```
54
55
**Usage Example:**
56
57
```typescript
58
import type { DeepMarkOptional } from "ts-essentials";
59
60
type User = {
61
id: number;
62
profile: {
63
name: string;
64
settings: {
65
theme: string;
66
lang: string;
67
};
68
};
69
};
70
71
type OptionalTheme = DeepMarkOptional<User, "profile.settings.theme">;
72
// Makes the nested theme property optional while keeping everything else required
73
```
74
75
### DeepMarkRequired
76
77
Constructs a type by picking all properties from type `Type` where properties by paths `KeyPathUnion` are set as required recursively.
78
79
```typescript { .api }
80
type DeepMarkRequired<Type, KeyPathUnion extends Paths<Type>> = /* complex recursive type */;
81
```
82
83
**Usage Example:**
84
85
```typescript
86
import type { DeepMarkRequired } from "ts-essentials";
87
88
type PartialUser = {
89
id?: number;
90
profile?: {
91
name?: string;
92
settings?: {
93
theme?: string;
94
lang?: string;
95
};
96
};
97
};
98
99
type RequiredName = DeepMarkRequired<PartialUser, "profile.name">;
100
// Makes the nested name property required while keeping others optional
101
```
102
103
### DeepNonNullable
104
105
Constructs a type by picking all properties from type `Type` recursively and exclude `null` and `undefined` property values from all of them.
106
107
```typescript { .api }
108
type DeepNonNullable<Type> = Type extends Function
109
? Type
110
: Type extends any[]
111
? DeepNonNullableArray<Type>
112
: Type extends ReadonlyArray<any>
113
? DeepNonNullableReadonlyArray<Type>
114
: DeepNonNullableObject<Type>;
115
116
type DeepNonNullableObject<Type> = {
117
[Key in keyof Type]-?: DeepNonNullable<NonNullable<Type[Key]>>;
118
};
119
```
120
121
**Usage Example:**
122
123
```typescript
124
import type { DeepNonNullable } from "ts-essentials";
125
126
type User = {
127
id: number | null;
128
profile: {
129
name: string | undefined;
130
avatar: string | null;
131
settings?: {
132
theme: string | null;
133
};
134
} | null;
135
};
136
137
type CleanUser = DeepNonNullable<User>;
138
// Result: All null and undefined removed recursively
139
// {
140
// id: number;
141
// profile: {
142
// name: string;
143
// avatar: string;
144
// settings: {
145
// theme: string;
146
// };
147
// };
148
// }
149
```
150
151
### DeepNullable
152
153
Constructs a type by picking all properties from type `Type` recursively and include `null` property values for all of them.
154
155
```typescript { .api }
156
type DeepNullable<Type> = Type extends Function
157
? Type
158
: Type extends any[]
159
? DeepNullableArray<Type>
160
: Type extends ReadonlyArray<any>
161
? DeepNullableReadonlyArray<Type>
162
: DeepNullableObject<Type>;
163
164
type DeepNullableObject<Type> = {
165
[Key in keyof Type]: DeepNullable<Type[Key]> | null;
166
};
167
```
168
169
### DeepOmit
170
171
Constructs a type by picking all properties from type `Type` and removing properties which values are `never` or `true` in type `Filter`.
172
173
```typescript { .api }
174
type DeepOmit<Type, Filter> = Type extends any[]
175
? Type
176
: Type extends ReadonlyArray<any>
177
? Type
178
: DeepOmitObject<Type, Filter>;
179
```
180
181
**Usage Example:**
182
183
```typescript
184
import type { DeepOmit } from "ts-essentials";
185
186
type User = {
187
id: number;
188
password: string;
189
profile: {
190
name: string;
191
email: string;
192
secret: string;
193
};
194
};
195
196
type OmitFilter = {
197
password: true;
198
profile: {
199
secret: true;
200
};
201
};
202
203
type PublicUser = DeepOmit<User, OmitFilter>;
204
// Result: { id: number; profile: { name: string; email: string; } }
205
```
206
207
### DeepPartial
208
209
Constructs a type by picking all properties from type `Type` recursively and setting them as optional.
210
211
```typescript { .api }
212
type DeepPartial<Type> = Type extends Function
213
? Type
214
: Type extends Array<infer U>
215
? Array<DeepPartial<U>>
216
: Type extends ReadonlyArray<infer U>
217
? ReadonlyArray<DeepPartial<U>>
218
: { [K in keyof Type]?: DeepPartial<Type[K]> };
219
```
220
221
**Usage Example:**
222
223
```typescript
224
import type { DeepPartial } from "ts-essentials";
225
226
type User = {
227
id: number;
228
profile: {
229
name: string;
230
settings: {
231
theme: string;
232
notifications: boolean;
233
};
234
};
235
};
236
237
type PartialUser = DeepPartial<User>;
238
// Result: All properties optional recursively
239
// {
240
// id?: number;
241
// profile?: {
242
// name?: string;
243
// settings?: {
244
// theme?: string;
245
// notifications?: boolean;
246
// };
247
// };
248
// }
249
250
const update: PartialUser = {
251
profile: {
252
settings: {
253
theme: "dark"
254
// notifications can be omitted
255
}
256
// name can be omitted
257
}
258
// id can be omitted
259
};
260
```
261
262
### DeepPick
263
264
Constructs a type by picking set of properties, which have property values `never` or `true` in type `Filter`, from type `Type`.
265
266
```typescript { .api }
267
type DeepPick<Type, Filter> = Type extends any[]
268
? Type
269
: Type extends ReadonlyArray<any>
270
? Type
271
: DeepPickObject<Type, Filter>;
272
```
273
274
**Usage Example:**
275
276
```typescript
277
import type { DeepPick } from "ts-essentials";
278
279
type User = {
280
id: number;
281
password: string;
282
profile: {
283
name: string;
284
email: string;
285
avatar: string;
286
};
287
};
288
289
type PickFilter = {
290
id: true;
291
profile: {
292
name: true;
293
email: true;
294
};
295
};
296
297
type PublicUserInfo = DeepPick<User, PickFilter>;
298
// Result: { id: number; profile: { name: string; email: string; } }
299
```
300
301
### DeepReadonly
302
303
Constructs a type by picking all properties from type `Type` recursively and setting `readonly` modifier.
304
305
```typescript { .api }
306
type DeepReadonly<Type> = Type extends Function
307
? Type
308
: Type extends Array<infer U>
309
? ReadonlyArray<DeepReadonly<U>>
310
: { readonly [K in keyof Type]: DeepReadonly<Type[K]> };
311
```
312
313
**Usage Example:**
314
315
```typescript
316
import type { DeepReadonly } from "ts-essentials";
317
318
type User = {
319
id: number;
320
profile: {
321
name: string;
322
settings: {
323
theme: string;
324
};
325
};
326
};
327
328
type ImmutableUser = DeepReadonly<User>;
329
// Result: All properties readonly recursively
330
331
const user: ImmutableUser = {
332
id: 1,
333
profile: {
334
name: "Alice",
335
settings: {
336
theme: "dark"
337
}
338
}
339
};
340
341
// user.id = 2; // Error: readonly
342
// user.profile.name = "Bob"; // Error: readonly
343
// user.profile.settings.theme = "light"; // Error: readonly
344
```
345
346
### DeepRequired
347
348
Constructs a type by picking all properties from type `Type` recursively and setting as required.
349
350
```typescript { .api }
351
type DeepRequired<Type> = Type extends Function
352
? Type
353
: Type extends Array<infer U>
354
? Array<DeepRequired<NonNullable<U>>>
355
: Type extends ReadonlyArray<infer U>
356
? ReadonlyArray<DeepRequired<NonNullable<U>>>
357
: { [K in keyof Type]-?: DeepRequired<NonNullable<Type[K]>> };
358
```
359
360
**Usage Example:**
361
362
```typescript
363
import type { DeepRequired } from "ts-essentials";
364
365
type PartialUser = {
366
id?: number;
367
profile?: {
368
name?: string;
369
settings?: {
370
theme?: string;
371
};
372
};
373
};
374
375
type CompleteUser = DeepRequired<PartialUser>;
376
// Result: All properties required recursively
377
// {
378
// id: number;
379
// profile: {
380
// name: string;
381
// settings: {
382
// theme: string;
383
// };
384
// };
385
// }
386
```
387
388
### DeepUndefinable
389
390
Constructs a type by picking all properties from type `Type` recursively and include `undefined` property values for all of them.
391
392
```typescript { .api }
393
type DeepUndefinable<Type> = Type extends Function
394
? Type
395
: Type extends any[]
396
? DeepUndefinableArray<Type>
397
: Type extends ReadonlyArray<any>
398
? DeepUndefinableReadonlyArray<Type>
399
: DeepUndefinableObject<Type>;
400
401
type DeepUndefinableObject<Type> = {
402
[Key in keyof Type]: DeepUndefinable<Type[Key]> | undefined;
403
};
404
```
405
406
### DeepWritable
407
408
Constructs a type by picking all properties from type `Type` recursively and removing `readonly` modifier.
409
410
```typescript { .api }
411
type DeepWritable<Type> = Type extends Function
412
? Type
413
: Type extends ReadonlyArray<infer U>
414
? DeepWritable<U>[]
415
: { -readonly [K in keyof Type]: DeepWritable<Type[K]> };
416
```
417
418
**Usage Example:**
419
420
```typescript
421
import type { DeepWritable } from "ts-essentials";
422
423
type ImmutableUser = {
424
readonly id: number;
425
readonly profile: {
426
readonly name: string;
427
readonly settings: {
428
readonly theme: string;
429
};
430
};
431
};
432
433
type MutableUser = DeepWritable<ImmutableUser>;
434
// Result: All readonly modifiers removed recursively
435
436
const user: MutableUser = {
437
id: 1,
438
profile: {
439
name: "Alice",
440
settings: {
441
theme: "dark"
442
}
443
}
444
};
445
446
user.id = 2; // OK
447
user.profile.name = "Bob"; // OK
448
user.profile.settings.theme = "light"; // OK
449
```
450
451
### StrictDeepOmit
452
453
Constructs a type by picking all properties from type `Type` and removing properties which values are `never` or `true` in type `Filter`. The type `Filter` is validated against a structure of `Type`.
454
455
```typescript { .api }
456
type StrictDeepOmit<Type, Filter> = DeepOmit<Type, Filter>;
457
```
458
459
### StrictDeepPick
460
461
Constructs a type by picking set of properties, which have property values `never` or `true` in type `Filter`, from type `Type`. The type `Filter` is validated against a structure of `Type`.
462
463
```typescript { .api }
464
type StrictDeepPick<Type, Filter> = DeepPick<Type, Filter>;
465
```