0
# Object Module
1
2
Extensive object manipulation utilities providing property access, transformation operations, and deep path-based modifications. The second largest module with 55+ type utilities.
3
4
## Capabilities
5
6
### Property Access and Query
7
8
Access properties, check existence, and extract keys and values.
9
10
```typescript { .api }
11
/**
12
* Access property at key K in object O
13
* @param O - Object type to access
14
* @param K - Key to access
15
* @returns Property type at key K
16
*/
17
type At<O extends Object, K extends keyof O> = O[K];
18
19
/**
20
* Check if object O has property K
21
* @param O - Object type to check
22
* @param K - Key to check for
23
* @returns 1 if property exists, 0 otherwise
24
*/
25
type Has<O extends Object, K extends Key> = K extends keyof O ? 1 : 0;
26
27
/**
28
* Extract all keys from object O
29
* @param O - Object type to extract keys from
30
* @returns Union of all keys
31
*/
32
type Keys<O extends Object> = keyof O;
33
34
/**
35
* Extract known keys (non-index signature) from object O
36
* @param O - Object type to extract known keys from
37
* @returns Union of known keys
38
*/
39
type KnownKeys<O extends Object> = keyof O;
40
41
/**
42
* Extract all values from object O
43
* @param O - Object type to extract values from
44
* @returns Union of all property values
45
*/
46
type Values<O extends Object> = O[keyof O];
47
48
/**
49
* Generate all possible paths to properties in object O
50
* @param O - Object type to generate paths for
51
* @returns Union of all property paths
52
*/
53
type Paths<O extends Object> = PathsImpl<O>;
54
```
55
56
**Usage Examples:**
57
58
```typescript
59
import { O } from "ts-toolbelt";
60
61
type User = {
62
name: string;
63
age: number;
64
address: { street: string; city: string };
65
};
66
67
type Name = O.At<User, "name">; // string
68
type HasEmail = O.Has<User, "email">; // 0
69
type HasName = O.Has<User, "name">; // 1
70
type UserKeys = O.Keys<User>; // "name" | "age" | "address"
71
type UserValues = O.Values<User>; // string | number | { street: string; city: string }
72
type UserPaths = O.Paths<User>; // "name" | "age" | "address" | "address.street" | "address.city"
73
```
74
75
### Advanced Key Operations
76
77
Additional key-based operations for filtering, selecting, and working with object keys.
78
79
```typescript { .api }
80
/**
81
* Get the keys of O which fields match M
82
* @param O - Object to extract from
83
* @param M - Type to select fields
84
* @param match - Precision mode for matching
85
* @returns Union of keys whose values match M
86
*/
87
type SelectKeys<O extends Object, M extends any, match extends Match = 'default'> = SelectKeysImpl<O, M, match>;
88
89
/**
90
* Filter out the keys of O which fields match M
91
* @param O - Object to remove from
92
* @param M - Type to select fields
93
* @param match - Precision mode for matching
94
* @returns Union of keys whose values don't match M
95
*/
96
type FilterKeys<O extends Object, M extends any, match extends Match = 'default'> = FilterKeysImpl<O, M, match>;
97
98
/**
99
* Get the intersecting keys of O & O1
100
* @param O - Object to check similarities with
101
* @param O1 - Object to check similarities against
102
* @param match - Precision mode for matching
103
* @returns Union of common keys
104
*/
105
type IntersectKeys<O extends Object, O1 extends Object, match extends Match = 'default'> = IntersectKeysImpl<O, O1, match>;
106
107
/**
108
* Exclude the keys of O1 out of the keys of O
109
* @param O - Object to remove keys from
110
* @param O1 - Object whose keys to remove
111
* @param match - Precision mode for matching
112
* @returns Union of keys in O but not in O1
113
*/
114
type ExcludeKeys<O extends Object, O1 extends Object, match extends Match = 'default'> = ExcludeKeysImpl<O, O1, match>;
115
```
116
117
### Nullable Key Operations
118
119
Operations for working with nullable, non-nullable, and undefinable keys.
120
121
```typescript { .api }
122
/**
123
* Get the keys of O that are non-nullable
124
* @param O - Object to extract from
125
* @returns Union of non-nullable keys
126
*/
127
type NonNullableKeys<O extends Object> = NonNullableKeysImpl<O>;
128
129
/**
130
* Get the keys of O that are nullable
131
* @param O - Object to extract from
132
* @returns Union of nullable keys
133
*/
134
type NullableKeys<O extends Object> = NullableKeysImpl<O>;
135
136
/**
137
* Get the keys of O that are undefinable
138
* @param O - Object to extract from
139
* @returns Union of undefinable keys
140
*/
141
type UndefinableKeys<O extends Object> = UndefinableKeysImpl<O>;
142
```
143
144
### Core Transformations
145
146
Essential object transformation operations for creating new object types.
147
148
```typescript { .api }
149
/**
150
* Pick specific properties from object O
151
* @param O - Object type to pick from
152
* @param K - Keys to pick
153
* @returns New object with only picked properties
154
*/
155
type Pick<O extends Object, K extends keyof O> = { [P in K]: O[P] } & {};
156
157
/**
158
* Omit specific properties from object O
159
* @param O - Object type to omit from
160
* @param K - Keys to omit
161
* @returns New object without omitted properties
162
*/
163
type Omit<O extends Object, K extends keyof O> = Pick<O, Exclude<keyof O, K>>;
164
165
/**
166
* Merge two objects with optional depth control
167
* @param O1 - First object to merge
168
* @param O2 - Second object to merge
169
* @param depth - Merge depth: 'flat' or 'deep'
170
* @returns Merged object type
171
*/
172
type Merge<O1 extends Object, O2 extends Object, depth extends 'flat' | 'deep' = 'flat'> =
173
depth extends 'flat' ? O1 & O2 : MergeDeep<O1, O2>;
174
175
/**
176
* Merge multiple objects into one
177
* @param Os - Array of object types to merge
178
* @returns Single merged object type
179
*/
180
type MergeAll<Os extends readonly Object[]> = MergeAllImpl<Os>;
181
182
/**
183
* Assign properties from source to target object
184
* @param O - Target object type
185
* @param O1 - Source object type
186
* @returns Object with assigned properties
187
*/
188
type Assign<O extends Object, O1 extends Object> = O & O1;
189
```
190
191
**Usage Examples:**
192
193
```typescript
194
import { O } from "ts-toolbelt";
195
196
type User = { name: string; age: number; email: string; active: boolean };
197
198
type BasicUser = O.Pick<User, "name" | "age">; // { name: string; age: number }
199
type PublicUser = O.Omit<User, "email">; // { name: string; age: number; active: boolean }
200
201
type Address = { street: string; city: string };
202
type UserWithAddress = O.Merge<User, Address>;
203
// { name: string; age: number; email: string; active: boolean; street: string; city: string }
204
205
// Deep merge example
206
type UserProfile = { user: { name: string } };
207
type UserDetails = { user: { age: number } };
208
type FullProfile = O.Merge<UserProfile, UserDetails, 'deep'>;
209
// { user: { name: string; age: number } }
210
211
type MultiMerge = O.MergeAll<[User, Address, { score: number }]>;
212
// { name: string; age: number; email: string; active: boolean; street: string; city: string; score: number }
213
```
214
215
### Object Operations
216
217
Advanced object operations including exclusion, intersection, and validation.
218
219
```typescript { .api }
220
/**
221
* Exclude the fields of O1 out of O
222
* @param O - Object to remove from
223
* @param O1 - Object whose fields to remove
224
* @param match - Precision mode for matching
225
* @returns Object with O1 fields removed
226
*/
227
type Exclude<O extends Object, O1 extends Object, match extends Match = 'default'> = Pick<O, ExcludeKeys<O, O1, match>>;
228
229
/**
230
* Get the intersecting fields of O & O1
231
* @param O - Object to check similarities with
232
* @param O1 - Object to check similarities against
233
* @param match - Precision mode for matching
234
* @returns Object with only common fields
235
*/
236
type Intersect<O extends Object, O1 extends Object, match extends Match = 'default'> = Pick<O, IntersectKeys<O, O1, match>>;
237
238
/**
239
* Check whether O has fields that match M
240
* @param O - Object to be inspected
241
* @param M - Type to check field type
242
* @param match - Precision mode for matching
243
* @returns 1 if match found, 0 otherwise
244
*/
245
type Includes<O extends Object, M extends any, match extends Match = 'default'> = [SelectKeys<O, M, match>] extends [never] ? 0 : 1;
246
247
/**
248
* Swap the keys and values of an object
249
* @param O - Object to invert
250
* @returns Object with keys and values swapped
251
*/
252
type Invert<O extends Record<keyof O, Key>> = InvertImpl<O>;
253
254
/**
255
* Make the fields of O union the ones of O1
256
* @param O - Object to union from
257
* @param O1 - Object to union with
258
* @param K - Keys to choose fields
259
* @returns Object with unionized field types
260
*/
261
type Unionize<O extends Object, O1 extends Object, K extends Key = Key> = {
262
[P in keyof O]: P extends K ? O[P] | At<O1, P> : O[P];
263
} & {};
264
```
265
266
### Constraint Operations
267
268
Operations for applying constraints and requirements to object types.
269
270
```typescript { .api }
271
/**
272
* Make that at least one of the keys K are required in O at a time
273
* @param O - Object to make required
274
* @param K - Keys to choose fields
275
* @returns Object union with at least one required key
276
*/
277
type AtLeast<O extends object, K extends Key = Keys<O>> = O extends unknown ? _AtLeast<O, K> : never;
278
279
/**
280
* Split O into a union where none of the K keys are present together
281
* @param O - Object to split
282
* @param K - Keys to split with
283
* @param strict - Force excess property checks
284
* @returns Object union with mutually exclusive keys
285
*/
286
type Either<O extends object, K extends Key, strict extends Boolean = 1> = O extends unknown ? _Either<O, K, strict> : never;
287
```
288
289
### Transformation Operations
290
291
Operations for transforming objects into other types.
292
293
```typescript { .api }
294
/**
295
* Transform an object into a list
296
* @param O - Object to transform
297
* @returns List representation of object
298
*/
299
type ListOf<O extends Object> = ListOfImpl<O>;
300
301
/**
302
* Transform an object into a union of its values
303
* @param O - Object to transform
304
* @returns Union of all property values
305
*/
306
type UnionOf<O extends Object> = UnionOfImpl<O>;
307
308
/**
309
* Merge a list of objects into O
310
* @param O - Object to start with
311
* @param Os - List of objects to merge
312
* @param depth - Merge depth ('flat' or 'deep')
313
* @param ignore - Types not to merge
314
* @param fill - Types to be replaced
315
* @returns Merged object
316
*/
317
type MergeAll<O extends Object, Os extends List<Object>, depth extends Depth = 'flat', ignore extends Object = BuiltIn, fill extends any = undefined> = MergeAllImpl<O, Os, depth, ignore, fill>;
318
319
/**
320
* Patch a list of objects into O
321
* @param O - Object to start with
322
* @param Os - List of objects to patch
323
* @param depth - Patch depth ('flat' or 'deep')
324
* @param ignore - Types not to merge
325
* @param fill - Types to be replaced
326
* @returns Patched object
327
*/
328
type PatchAll<O extends Object, Os extends List<Object>, depth extends Depth = 'flat', ignore extends Object = BuiltIn, fill extends any = never> = PatchAllImpl<O, Os, depth, ignore, fill>;
329
```
330
331
### Utility Types
332
333
Core utility types for object operations.
334
335
```typescript { .api }
336
/**
337
* An Object type
338
* @returns Record with any keys and values
339
*/
340
type Object = Record<Key, any>;
341
342
/**
343
* Create an object filled with A for the fields K
344
* @param K - Keys to choose fields
345
* @param A - Type to fill fields with
346
* @param modx - Modifiers for readonly/optional
347
* @returns Object record type
348
*/
349
type Record<K extends Key, A extends any = unknown, modx extends Modx = ['!', 'W']> = {
350
'!': {
351
'R': { readonly [P in K]: A };
352
'W': { [P in K]: A };
353
};
354
'?': {
355
'R': { readonly [P in K]?: A };
356
'W': { [P in K]?: A };
357
};
358
}[modx[0]][modx[1]];
359
```
360
361
### Property Modifications
362
363
Modify property characteristics like optionality, readonly status, and nullability.
364
365
```typescript { .api }
366
/**
367
* Make all properties optional
368
* @param O - Object type to make partial
369
* @returns Object with all optional properties
370
*/
371
type Partial<O extends Object> = { [K in keyof O]?: O[K] };
372
373
/**
374
* Make all properties required
375
* @param O - Object type to make required
376
* @returns Object with all required properties
377
*/
378
type Required<O extends Object> = { [K in keyof O]-?: O[K] };
379
380
/**
381
* Make all properties readonly
382
* @param O - Object type to make readonly
383
* @returns Object with all readonly properties
384
*/
385
type Readonly<O extends Object> = { readonly [K in keyof O]: O[K] };
386
387
/**
388
* Make all properties writable (remove readonly)
389
* @param O - Object type to make writable
390
* @returns Object with all writable properties
391
*/
392
type Writable<O extends Object> = { -readonly [K in keyof O]: O[K] };
393
394
/**
395
* Make all properties nullable
396
* @param O - Object type to make nullable
397
* @returns Object with all nullable properties
398
*/
399
type Nullable<O extends Object> = { [K in keyof O]: O[K] | null };
400
401
/**
402
* Remove null and undefined from all properties
403
* @param O - Object type to make non-nullable
404
* @returns Object with non-nullable properties
405
*/
406
type NonNullable<O extends Object> = { [K in keyof O]: NonNullable<O[K]> };
407
408
/**
409
* Make specific properties compulsory (required)
410
* @param O - Object type to modify
411
* @param K - Keys to make compulsory
412
* @returns Object with specified properties made required
413
*/
414
type Compulsory<O extends Object, K extends keyof O> = O & Required<Pick<O, K>>;
415
416
/**
417
* Make specific properties optional
418
* @param O - Object type to modify
419
* @param K - Keys to make optional
420
* @returns Object with specified properties made optional
421
*/
422
type Optional<O extends Object, K extends keyof O> = Omit<O, K> & Partial<Pick<O, K>>;
423
```
424
425
**Usage Examples:**
426
427
```typescript
428
import { O } from "ts-toolbelt";
429
430
type User = {
431
readonly name: string;
432
age: number;
433
email?: string;
434
active: boolean | null;
435
};
436
437
type PartialUser = O.Partial<User>;
438
// { readonly name?: string; age?: number; email?: string; active?: boolean | null }
439
440
type RequiredUser = O.Required<User>;
441
// { readonly name: string; age: number; email: string; active: boolean | null }
442
443
type ReadonlyUser = O.Readonly<User>;
444
// { readonly name: string; readonly age: number; readonly email?: string; readonly active: boolean | null }
445
446
type WritableUser = O.Writable<User>;
447
// { name: string; age: number; email?: string; active: boolean | null }
448
449
type NullableUser = O.Nullable<User>;
450
// { readonly name: string | null; age: number | null; email?: string | null; active: boolean | null }
451
452
type NonNullUser = O.NonNullable<User>;
453
// { readonly name: string; age: number; email?: string; active: boolean }
454
455
type CompulsoryEmail = O.Compulsory<User, "email">;
456
// { readonly name: string; age: number; email: string; active: boolean | null }
457
458
type OptionalAge = O.Optional<User, "age">;
459
// { readonly name: string; age?: number; email?: string; active: boolean | null }
460
```
461
462
### Property Operations
463
464
Advanced property manipulation including filtering, updating, and selective operations.
465
466
```typescript { .api }
467
/**
468
* Filter object properties based on condition
469
* @param O - Object type to filter
470
* @param M - Condition to filter by
471
* @returns Object with filtered properties
472
*/
473
type Filter<O extends Object, M> = FilterImpl<O, M>;
474
475
/**
476
* Update specific properties with new values
477
* @param O - Object type to update
478
* @param Path - Path to property to update
479
* @param A - New value type
480
* @returns Object with updated property
481
*/
482
type Update<O extends Object, Path extends string, A> = UpdateImpl<O, Path, A>;
483
484
/**
485
* Modify properties using transformation function
486
* @param O - Object type to modify
487
* @param M - Modification mapping
488
* @returns Object with modified properties
489
*/
490
type Modify<O extends Object, M> = ModifyImpl<O, M>;
491
492
/**
493
* Replace properties with new types
494
* @param O - Object type to modify
495
* @param M - Replacement mapping
496
* @returns Object with replaced properties
497
*/
498
type Replace<O extends Object, M extends Object> = Omit<O, keyof M> & M;
499
500
/**
501
* Patch object with new properties (shallow merge)
502
* @param O - Object type to patch
503
* @param O1 - Properties to patch with
504
* @returns Patched object
505
*/
506
type Patch<O extends Object, O1 extends Object> = O & O1;
507
508
/**
509
* Overwrite properties from source object
510
* @param O - Target object type
511
* @param O1 - Source object type
512
* @param K - Keys to overwrite
513
* @returns Object with overwritten properties
514
*/
515
type Overwrite<O extends Object, O1 extends Object, K extends keyof O & keyof O1 = keyof O & keyof O1> =
516
Omit<O, K> & Pick<O1, K>;
517
```
518
519
**Usage Examples:**
520
521
```typescript
522
import { O } from "ts-toolbelt";
523
524
type User = { name: string; age: number; email: string; active: boolean };
525
526
// Filter only string properties
527
type StringProps = O.Filter<User, string>; // { name: string; email: string }
528
529
// Update nested property
530
type UserProfile = { user: User; settings: { theme: string } };
531
type UpdatedProfile = O.Update<UserProfile, "settings.theme", "dark">;
532
// { user: User; settings: { theme: "dark" } }
533
534
// Replace properties
535
type UserUpdates = { age: string; score: number };
536
type UpdatedUser = O.Replace<User, UserUpdates>;
537
// { name: string; age: string; email: string; active: boolean; score: number }
538
539
// Patch with new properties
540
type UserExtensions = { lastLogin: Date; preferences: string[] };
541
type ExtendedUser = O.Patch<User, UserExtensions>;
542
// { name: string; age: number; email: string; active: boolean; lastLogin: Date; preferences: string[] }
543
544
// Overwrite specific properties
545
type NewUserData = { age: string; active: string };
546
type OverwrittenUser = O.Overwrite<User, NewUserData>;
547
// { name: string; age: string; email: string; active: string }
548
```
549
550
### Path-Based Operations
551
552
Deep object manipulation using path notation for nested property access.
553
554
```typescript { .api }
555
/**
556
* Path-based property access using dot notation
557
* @param O - Object type to access
558
* @param Path - Dot-separated path to property
559
* @returns Property type at path
560
*/
561
type AtPath<O extends Object, Path extends string> = AtPathImpl<O, Path>;
562
563
/**
564
* Check if path exists in object
565
* @param O - Object type to check
566
* @param Path - Path to check for
567
* @returns 1 if path exists, 0 otherwise
568
*/
569
type HasPath<O extends Object, Path extends string> = HasPathImpl<O, Path>;
570
571
/**
572
* Namespace for path-based operations
573
*/
574
namespace P {
575
type Pick<O extends Object, Path extends string> = PickPathImpl<O, Path>;
576
type Omit<O extends Object, Path extends string> = OmitPathImpl<O, Path>;
577
type Update<O extends Object, Path extends string, A> = UpdatePathImpl<O, Path, A>;
578
type Merge<O1 extends Object, O2 extends Object> = MergePathImpl<O1, O2>;
579
type Readonly<O extends Object, Path extends string> = ReadonlyPathImpl<O, Path>;
580
type Record<Path extends string, A> = RecordPathImpl<Path, A>;
581
}
582
```
583
584
**Usage Examples:**
585
586
```typescript
587
import { O } from "ts-toolbelt";
588
589
type UserProfile = {
590
user: {
591
name: string;
592
details: {
593
age: number;
594
address: {
595
street: string;
596
city: string;
597
};
598
};
599
};
600
settings: {
601
theme: string;
602
notifications: boolean;
603
};
604
};
605
606
type UserName = O.AtPath<UserProfile, "user.name">; // string
607
type UserAge = O.AtPath<UserProfile, "user.details.age">; // number
608
type City = O.AtPath<UserProfile, "user.details.address.city">; // string
609
610
type HasTheme = O.HasPath<UserProfile, "settings.theme">; // 1
611
type HasInvalidPath = O.HasPath<UserProfile, "user.invalid">; // 0
612
613
// Path-based operations using P namespace
614
type PickUserName = O.P.Pick<UserProfile, "user.name">;
615
// { user: { name: string } }
616
617
type UpdateAge = O.P.Update<UserProfile, "user.details.age", string>;
618
// UserProfile with age changed to string
619
620
type MergeSettings = O.P.Merge<UserProfile, { settings: { language: string } }>;
621
// UserProfile with settings.language added
622
```
623
624
### Key Extraction
625
626
Extract different types of keys based on property characteristics.
627
628
```typescript { .api }
629
/**
630
* Extract keys of properties that are optional
631
* @param O - Object type to extract from
632
* @returns Union of optional property keys
633
*/
634
type OptionalKeys<O extends Object> = OptionalKeysImpl<O>;
635
636
/**
637
* Extract keys of properties that are required
638
* @param O - Object type to extract from
639
* @returns Union of required property keys
640
*/
641
type RequiredKeys<O extends Object> = RequiredKeysImpl<O>;
642
643
/**
644
* Extract keys of properties that are readonly
645
* @param O - Object type to extract from
646
* @returns Union of readonly property keys
647
*/
648
type ReadonlyKeys<O extends Object> = ReadonlyKeysImpl<O>;
649
650
/**
651
* Extract keys of properties that are writable
652
* @param O - Object type to extract from
653
* @returns Union of writable property keys
654
*/
655
type WritableKeys<O extends Object> = WritableKeysImpl<O>;
656
657
/**
658
* Extract keys of properties that can be undefined
659
* @param O - Object type to extract from
660
* @returns Union of undefinable property keys
661
*/
662
type UndefinableKeys<O extends Object> = UndefinableKeysImpl<O>;
663
664
/**
665
* Extract keys of properties that are compulsory (required and not undefined)
666
* @param O - Object type to extract from
667
* @returns Union of compulsory property keys
668
*/
669
type CompulsoryKeys<O extends Object> = CompulsoryKeysImpl<O>;
670
```
671
672
**Usage Examples:**
673
674
```typescript
675
import { O } from "ts-toolbelt";
676
677
type User = {
678
readonly id: string;
679
name: string;
680
age?: number;
681
email?: string;
682
active: boolean | undefined;
683
};
684
685
type OptionalKeys = O.OptionalKeys<User>; // "age" | "email"
686
type RequiredKeys = O.RequiredKeys<User>; // "id" | "name" | "active"
687
type ReadonlyKeys = O.ReadonlyKeys<User>; // "id"
688
type WritableKeys = O.WritableKeys<User>; // "name" | "age" | "email" | "active"
689
type UndefinableKeys = O.UndefinableKeys<User>; // "age" | "email" | "active"
690
type CompulsoryKeys = O.CompulsoryKeys<User>; // "id" | "name"
691
```
692
693
## Types
694
695
```typescript { .api }
696
// Core types used by Object module
697
type Object = Record<string | number | symbol, any>;
698
type Key = string | number | symbol;
699
```