@visulima/object 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,2464 +1,7 @@
1
- /**
2
- Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
3
-
4
- @category Type
5
- */
6
- type Primitive =
7
- | null
8
- | undefined
9
- | string
10
- | number
11
- | boolean
12
- | symbol
13
- | bigint;
14
-
15
- declare global {
16
- // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged.
17
- interface SymbolConstructor {
18
- readonly observable: symbol;
19
- }
20
- }
21
-
22
- /**
23
- Convert a union type to an intersection type using [distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
24
-
25
- Inspired by [this Stack Overflow answer](https://stackoverflow.com/a/50375286/2172153).
26
-
27
- @example
28
- ```
29
- import type {UnionToIntersection} from 'type-fest';
30
-
31
- type Union = {the(): void} | {great(arg: string): void} | {escape: boolean};
32
-
33
- type Intersection = UnionToIntersection<Union>;
34
- //=> {the(): void; great(arg: string): void; escape: boolean};
35
- ```
36
-
37
- A more applicable example which could make its way into your library code follows.
38
-
39
- @example
40
- ```
41
- import type {UnionToIntersection} from 'type-fest';
42
-
43
- class CommandOne {
44
- commands: {
45
- a1: () => undefined,
46
- b1: () => undefined,
47
- }
48
- }
49
-
50
- class CommandTwo {
51
- commands: {
52
- a2: (argA: string) => undefined,
53
- b2: (argB: string) => undefined,
54
- }
55
- }
56
-
57
- const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
58
- type Union = typeof union;
59
- //=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
60
-
61
- type Intersection = UnionToIntersection<Union>;
62
- //=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
63
- ```
64
-
65
- @category Type
66
- */
67
- type UnionToIntersection<Union> = (
68
- // `extends unknown` is always going to be the case and is used to convert the
69
- // `Union` into a [distributive conditional
70
- // type](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
71
- Union extends unknown
72
- // The union type is used as the only argument to a function since the union
73
- // of function arguments is an intersection.
74
- ? (distributedUnion: Union) => void
75
- // This won't happen.
76
- : never
77
- // Infer the `Intersection` type since TypeScript represents the positional
78
- // arguments of unions of functions as an intersection of the union.
79
- ) extends ((mergedIntersection: infer Intersection) => void)
80
- // The `& Union` is to allow indexing by the resulting type
81
- ? Intersection & Union
82
- : never;
83
-
84
- declare const emptyObjectSymbol: unique symbol;
85
-
86
- /**
87
- Represents a strictly empty plain object, the `{}` value.
88
-
89
- When you annotate something as the type `{}`, it can be anything except `null` and `undefined`. This means that you cannot use `{}` to represent an empty plain object ([read more](https://stackoverflow.com/questions/47339869/typescript-empty-object-and-any-difference/52193484#52193484)).
90
-
91
- @example
92
- ```
93
- import type {EmptyObject} from 'type-fest';
94
-
95
- // The following illustrates the problem with `{}`.
96
- const foo1: {} = {}; // Pass
97
- const foo2: {} = []; // Pass
98
- const foo3: {} = 42; // Pass
99
- const foo4: {} = {a: 1}; // Pass
100
-
101
- // With `EmptyObject` only the first case is valid.
102
- const bar1: EmptyObject = {}; // Pass
103
- const bar2: EmptyObject = 42; // Fail
104
- const bar3: EmptyObject = []; // Fail
105
- const bar4: EmptyObject = {a: 1}; // Fail
106
- ```
107
-
108
- Unfortunately, `Record<string, never>`, `Record<keyof any, never>` and `Record<never, never>` do not work. See {@link https://github.com/sindresorhus/type-fest/issues/395 #395}.
109
-
110
- @category Object
111
- */
112
- type EmptyObject = {[emptyObjectSymbol]?: never};
113
-
114
- /**
115
- Returns a boolean for whether the two given types are equal.
116
-
117
- @link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
118
- @link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796
119
-
120
- Use-cases:
121
- - If you want to make a conditional branch based on the result of a comparison of two types.
122
-
123
- @example
124
- ```
125
- import type {IsEqual} from 'type-fest';
126
-
127
- // This type returns a boolean for whether the given array includes the given item.
128
- // `IsEqual` is used to compare the given array at position 0 and the given item and then return true if they are equal.
129
- type Includes<Value extends readonly any[], Item> =
130
- Value extends readonly [Value[0], ...infer rest]
131
- ? IsEqual<Value[0], Item> extends true
132
- ? true
133
- : Includes<rest, Item>
134
- : false;
135
- ```
136
-
137
- @category Type Guard
138
- @category Utilities
139
- */
140
- type IsEqual<A, B> =
141
- (<G>() => G extends A & G | G ? 1 : 2) extends
142
- (<G>() => G extends B & G | G ? 1 : 2)
143
- ? true
144
- : false;
145
-
146
- /**
147
- Represents an array with `unknown` value.
148
-
149
- Use case: You want a type that all arrays can be assigned to, but you don't care about the value.
150
-
151
- @example
152
- ```
153
- import type {UnknownArray} from 'type-fest';
154
-
155
- type IsArray<T> = T extends UnknownArray ? true : false;
156
-
157
- type A = IsArray<['foo']>;
158
- //=> true
159
-
160
- type B = IsArray<readonly number[]>;
161
- //=> true
162
-
163
- type C = IsArray<string>;
164
- //=> false
165
- ```
166
-
167
- @category Type
168
- @category Array
169
- */
170
- type UnknownArray = readonly unknown[];
171
-
172
- /**
173
- Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
174
-
175
- @example
176
- ```
177
- import type {Simplify} from 'type-fest';
178
-
179
- type PositionProps = {
180
- top: number;
181
- left: number;
182
- };
183
-
184
- type SizeProps = {
185
- width: number;
186
- height: number;
187
- };
188
-
189
- // In your editor, hovering over `Props` will show a flattened object with all the properties.
190
- type Props = Simplify<PositionProps & SizeProps>;
191
- ```
192
-
193
- Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface.
194
-
195
- If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`.
196
-
197
- @example
198
- ```
199
- import type {Simplify} from 'type-fest';
200
-
201
- interface SomeInterface {
202
- foo: number;
203
- bar?: string;
204
- baz: number | undefined;
205
- }
206
-
207
- type SomeType = {
208
- foo: number;
209
- bar?: string;
210
- baz: number | undefined;
211
- };
212
-
213
- const literal = {foo: 123, bar: 'hello', baz: 456};
214
- const someType: SomeType = literal;
215
- const someInterface: SomeInterface = literal;
216
-
217
- function fn(object: Record<string, unknown>): void {}
218
-
219
- fn(literal); // Good: literal object type is sealed
220
- fn(someType); // Good: type is sealed
221
- fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
222
- fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
223
- ```
224
-
225
- @link https://github.com/microsoft/TypeScript/issues/15300
226
- @see SimplifyDeep
227
- @category Object
228
- */
229
- type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
230
-
231
- /**
232
- Returns a boolean for whether the given type is `never`.
233
-
234
- @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
235
- @link https://stackoverflow.com/a/53984913/10292952
236
- @link https://www.zhenghao.io/posts/ts-never
237
-
238
- Useful in type utilities, such as checking if something does not occur.
239
-
240
- @example
241
- ```
242
- import type {IsNever, And} from 'type-fest';
243
-
244
- // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
245
- type AreStringsEqual<A extends string, B extends string> =
246
- And<
247
- IsNever<Exclude<A, B>> extends true ? true : false,
248
- IsNever<Exclude<B, A>> extends true ? true : false
249
- >;
250
-
251
- type EndIfEqual<I extends string, O extends string> =
252
- AreStringsEqual<I, O> extends true
253
- ? never
254
- : void;
255
-
256
- function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
257
- if (input === output) {
258
- process.exit(0);
259
- }
260
- }
261
-
262
- endIfEqual('abc', 'abc');
263
- //=> never
264
-
265
- endIfEqual('abc', '123');
266
- //=> void
267
- ```
268
-
269
- @category Type Guard
270
- @category Utilities
271
- */
272
- type IsNever<T> = [T] extends [never] ? true : false;
273
-
274
- /**
275
- An if-else-like type that resolves depending on whether the given type is `never`.
276
-
277
- @see {@link IsNever}
278
-
279
- @example
280
- ```
281
- import type {IfNever} from 'type-fest';
282
-
283
- type ShouldBeTrue = IfNever<never>;
284
- //=> true
285
-
286
- type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
287
- //=> 'bar'
288
- ```
289
-
290
- @category Type Guard
291
- @category Utilities
292
- */
293
- type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
294
- IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
295
- );
296
-
297
- /**
298
- Returns the static, fixed-length portion of the given array, excluding variable-length parts.
299
-
300
- @example
301
- ```
302
- type A = [string, number, boolean, ...string[]];
303
- type B = StaticPartOfArray<A>;
304
- //=> [string, number, boolean]
305
- ```
306
- */
307
- type StaticPartOfArray<T extends UnknownArray, Result extends UnknownArray = []> =
308
- T extends unknown
309
- ? number extends T['length'] ?
310
- T extends readonly [infer U, ...infer V]
311
- ? StaticPartOfArray<V, [...Result, U]>
312
- : Result
313
- : T
314
- : never; // Should never happen
315
-
316
- /**
317
- Returns the variable, non-fixed-length portion of the given array, excluding static-length parts.
318
-
319
- @example
320
- ```
321
- type A = [string, number, boolean, ...string[]];
322
- type B = VariablePartOfArray<A>;
323
- //=> string[]
324
- ```
325
- */
326
- type VariablePartOfArray<T extends UnknownArray> =
327
- T extends unknown
328
- ? T extends readonly [...StaticPartOfArray<T>, ...infer U]
329
- ? U
330
- : []
331
- : never; // Should never happen
332
-
333
- /**
334
- Set the given array to readonly if `IsReadonly` is `true`, otherwise set the given array to normal, then return the result.
335
-
336
- @example
337
- ```
338
- type ReadonlyArray = readonly string[];
339
- type NormalArray = string[];
340
-
341
- type ReadonlyResult = SetArrayAccess<NormalArray, true>;
342
- //=> readonly string[]
343
-
344
- type NormalResult = SetArrayAccess<ReadonlyArray, false>;
345
- //=> string[]
346
- ```
347
- */
348
- type SetArrayAccess<T extends UnknownArray, IsReadonly extends boolean> =
349
- T extends readonly [...infer U] ?
350
- IsReadonly extends true
351
- ? readonly [...U]
352
- : [...U]
353
- : T;
354
-
355
- /**
356
- Returns whether the given array `T` is readonly.
357
- */
358
- type IsArrayReadonly<T extends UnknownArray> = IfNever<T, false, T extends unknown[] ? false : true>;
359
-
360
- type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
361
-
362
- // Can eventually be replaced with the built-in once this library supports
363
- // TS5.4+ only. Tracked in https://github.com/sindresorhus/type-fest/issues/848
364
- type NoInfer<T> = T extends infer U ? U : never;
365
-
366
- /**
367
- Returns a boolean for whether the given type is `any`.
368
-
369
- @link https://stackoverflow.com/a/49928360/1490091
370
-
371
- Useful in type utilities, such as disallowing `any`s to be passed to a function.
372
-
373
- @example
374
- ```
375
- import type {IsAny} from 'type-fest';
376
-
377
- const typedObject = {a: 1, b: 2} as const;
378
- const anyObject: any = {a: 1, b: 2};
379
-
380
- function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {
381
- return obj[key];
382
- }
383
-
384
- const typedA = get(typedObject, 'a');
385
- //=> 1
386
-
387
- const anyA = get(anyObject, 'a');
388
- //=> any
389
- ```
390
-
391
- @category Type Guard
392
- @category Utilities
393
- */
394
- type IsAny<T> = 0 extends 1 & NoInfer<T> ? true : false;
395
-
396
- type Numeric = number | bigint;
397
-
398
- type Zero = 0 | 0n;
399
-
400
- /**
401
- Matches the hidden `Infinity` type.
402
-
403
- Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
404
-
405
- @see NegativeInfinity
406
-
407
- @category Numeric
408
- */
409
- // See https://github.com/microsoft/TypeScript/issues/31752
410
- // eslint-disable-next-line @typescript-eslint/no-loss-of-precision
411
- type PositiveInfinity = 1e999;
412
-
413
- /**
414
- Matches the hidden `-Infinity` type.
415
-
416
- Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/32277) if you want to have this type as a built-in in TypeScript.
417
-
418
- @see PositiveInfinity
419
-
420
- @category Numeric
421
- */
422
- // See https://github.com/microsoft/TypeScript/issues/31752
423
- // eslint-disable-next-line @typescript-eslint/no-loss-of-precision
424
- type NegativeInfinity = -1e999;
425
-
426
- /**
427
- A negative `number`/`bigint` (`-∞ < x < 0`)
428
-
429
- Use-case: Validating and documenting parameters.
430
-
431
- @see NegativeInteger
432
- @see NonNegative
433
-
434
- @category Numeric
435
- */
436
- type Negative<T extends Numeric> = T extends Zero ? never : `${T}` extends `-${string}` ? T : never;
437
-
438
- /**
439
- Returns a boolean for whether the given number is a negative number.
440
-
441
- @see Negative
442
-
443
- @example
444
- ```
445
- import type {IsNegative} from 'type-fest';
446
-
447
- type ShouldBeFalse = IsNegative<1>;
448
- type ShouldBeTrue = IsNegative<-1>;
449
- ```
450
-
451
- @category Numeric
452
- */
453
- type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
454
-
455
- /**
456
- Returns a boolean for whether two given types are both true.
457
-
458
- Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
459
-
460
- @example
461
- ```
462
- import type {And} from 'type-fest';
463
-
464
- And<true, true>;
465
- //=> true
466
-
467
- And<true, false>;
468
- //=> false
469
- ```
470
-
471
- @see {@link Or}
472
- */
473
- type And<A extends boolean, B extends boolean> = [A, B][number] extends true
474
- ? true
475
- : true extends [IsEqual<A, false>, IsEqual<B, false>][number]
476
- ? false
477
- : never;
478
-
479
- /**
480
- Returns a boolean for whether either of two given types are true.
481
-
482
- Use-case: Constructing complex conditional types where multiple conditions must be satisfied.
483
-
484
- @example
485
- ```
486
- import type {Or} from 'type-fest';
487
-
488
- Or<true, false>;
489
- //=> true
490
-
491
- Or<false, false>;
492
- //=> false
493
- ```
494
-
495
- @see {@link And}
496
- */
497
- type Or<A extends boolean, B extends boolean> = [A, B][number] extends false
498
- ? false
499
- : true extends [IsEqual<A, true>, IsEqual<B, true>][number]
500
- ? true
501
- : never;
502
-
503
- /**
504
- Returns a boolean for whether a given number is greater than another number.
505
-
506
- @example
507
- ```
508
- import type {GreaterThan} from 'type-fest';
509
-
510
- GreaterThan<1, -5>;
511
- //=> true
512
-
513
- GreaterThan<1, 1>;
514
- //=> false
515
-
516
- GreaterThan<1, 5>;
517
- //=> false
518
- ```
519
- */
520
- type GreaterThan<A extends number, B extends number> = number extends A | B
521
- ? never
522
- : [
523
- IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
524
- IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
525
- ] extends infer R extends [boolean, boolean, boolean, boolean]
526
- ? Or<
527
- And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
528
- And<IsEqual<R[3], true>, IsEqual<R[1], false>>
529
- > extends true
530
- ? true
531
- : Or<
532
- And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
533
- And<IsEqual<R[2], true>, IsEqual<R[0], false>>
534
- > extends true
535
- ? false
536
- : true extends R[number]
537
- ? false
538
- : [IsNegative<A>, IsNegative<B>] extends infer R extends [boolean, boolean]
539
- ? [true, false] extends R
540
- ? false
541
- : [false, true] extends R
542
- ? true
543
- : [false, false] extends R
544
- ? PositiveNumericStringGt<`${A}`, `${B}`>
545
- : PositiveNumericStringGt<`${NumberAbsolute<B>}`, `${NumberAbsolute<A>}`>
546
- : never
547
- : never;
548
-
549
- /**
550
- Returns a boolean for whether a given number is greater than or equal to another number.
551
-
552
- @example
553
- ```
554
- import type {GreaterThanOrEqual} from 'type-fest';
555
-
556
- GreaterThanOrEqual<1, -5>;
557
- //=> true
558
-
559
- GreaterThanOrEqual<1, 1>;
560
- //=> true
561
-
562
- GreaterThanOrEqual<1, 5>;
563
- //=> false
564
- ```
565
- */
566
- type GreaterThanOrEqual<A extends number, B extends number> = number extends A | B
567
- ? never
568
- : A extends B ? true : GreaterThan<A, B>;
569
-
570
- /**
571
- Returns a boolean for whether a given number is less than another number.
572
-
573
- @example
574
- ```
575
- import type {LessThan} from 'type-fest';
576
-
577
- LessThan<1, -5>;
578
- //=> false
579
-
580
- LessThan<1, 1>;
581
- //=> false
582
-
583
- LessThan<1, 5>;
584
- //=> true
585
- ```
586
- */
587
- type LessThan<A extends number, B extends number> = number extends A | B
588
- ? never
589
- : GreaterThanOrEqual<A, B> extends true ? false : true;
590
-
591
- /**
592
- Infer the length of the given tuple `<T>`.
593
-
594
- Returns `never` if the given type is an non-fixed-length array like `Array<string>`.
595
-
596
- @example
597
- ```
598
- type Tuple = TupleLength<[string, number, boolean]>;
599
- //=> 3
600
-
601
- type Array = TupleLength<string[]>;
602
- //=> never
603
-
604
- // Supports union types.
605
- type Union = TupleLength<[] | [1, 2, 3] | Array<number>>;
606
- //=> 1 | 3
607
- ```
608
- */
609
- type TupleLength<T extends UnknownArray> =
610
- // `extends unknown` is used to convert `T` (if `T` is a union type) to
611
- // a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types))
612
- T extends unknown
613
- ? number extends T['length']
614
- ? never // Return never if the given type is an non-flexed-length array like `Array<string>`
615
- : T['length']
616
- : never; // Should never happen
617
-
618
- /**
619
- Create a tuple type of the given length `<L>` and fill it with the given type `<Fill>`.
620
-
621
- If `<Fill>` is not provided, it will default to `unknown`.
622
-
623
- @link https://itnext.io/implementing-arithmetic-within-typescripts-type-system-a1ef140a6f6f
624
- */
625
- type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] = []> = number extends L
626
- ? Fill[]
627
- : L extends T['length']
628
- ? T
629
- : BuildTuple<L, Fill, [...T, Fill]>;
630
-
631
- /**
632
- Returns the maximum value from a tuple of integers.
633
-
634
- Note:
635
- - Float numbers are not supported.
636
-
637
- @example
638
- ```
639
- ArrayMax<[1, 2, 5, 3]>;
640
- //=> 5
641
-
642
- ArrayMax<[1, 2, 5, 3, 99, -1]>;
643
- //=> 99
644
- ```
645
- */
646
- type TupleMax<A extends number[], Result extends number = NegativeInfinity> = number extends A[number]
647
- ? never :
648
- A extends [infer F extends number, ...infer R extends number[]]
649
- ? GreaterThan<F, Result> extends true
650
- ? TupleMax<R, F>
651
- : TupleMax<R, Result>
652
- : Result;
653
-
654
- /**
655
- Returns the minimum value from a tuple of integers.
656
-
657
- Note:
658
- - Float numbers are not supported.
659
-
660
- @example
661
- ```
662
- ArrayMin<[1, 2, 5, 3]>;
663
- //=> 1
664
-
665
- ArrayMin<[1, 2, 5, 3, -5]>;
666
- //=> -5
667
- ```
668
- */
669
- type TupleMin<A extends number[], Result extends number = PositiveInfinity> = number extends A[number]
670
- ? never
671
- : A extends [infer F extends number, ...infer R extends number[]]
672
- ? LessThan<F, Result> extends true
673
- ? TupleMin<R, F>
674
- : TupleMin<R, Result>
675
- : Result;
676
-
677
- /**
678
- Return a string representation of the given string or number.
679
-
680
- Note: This type is not the return type of the `.toString()` function.
681
- */
682
- type ToString<T> = T extends string | number ? `${T}` : never;
683
-
684
- /**
685
- Converts a numeric string to a number.
686
-
687
- @example
688
- ```
689
- type PositiveInt = StringToNumber<'1234'>;
690
- //=> 1234
691
-
692
- type NegativeInt = StringToNumber<'-1234'>;
693
- //=> -1234
694
-
695
- type PositiveFloat = StringToNumber<'1234.56'>;
696
- //=> 1234.56
697
-
698
- type NegativeFloat = StringToNumber<'-1234.56'>;
699
- //=> -1234.56
700
-
701
- type PositiveInfinity = StringToNumber<'Infinity'>;
702
- //=> Infinity
703
-
704
- type NegativeInfinity = StringToNumber<'-Infinity'>;
705
- //=> -Infinity
706
- ```
707
-
708
- @category String
709
- @category Numeric
710
- @category Template literal
711
- */
712
- type StringToNumber<S extends string> = S extends `${infer N extends number}`
713
- ? N
714
- : S extends 'Infinity'
715
- ? PositiveInfinity
716
- : S extends '-Infinity'
717
- ? NegativeInfinity
718
- : never;
719
-
720
- /**
721
- Returns an array of the characters of the string.
722
-
723
- @example
724
- ```
725
- StringToArray<'abcde'>;
726
- //=> ['a', 'b', 'c', 'd', 'e']
727
-
728
- StringToArray<string>;
729
- //=> never
730
- ```
731
-
732
- @category String
733
- */
734
- type StringToArray<S extends string, Result extends string[] = []> = string extends S
735
- ? never
736
- : S extends `${infer F}${infer R}`
737
- ? StringToArray<R, [...Result, F]>
738
- : Result;
739
-
740
- /**
741
- Returns the length of the given string.
742
-
743
- @example
744
- ```
745
- StringLength<'abcde'>;
746
- //=> 5
747
-
748
- StringLength<string>;
749
- //=> never
750
- ```
751
-
752
- @category String
753
- @category Template literal
754
- */
755
- type StringLength<S extends string> = string extends S
756
- ? never
757
- : StringToArray<S>['length'];
758
-
759
- /**
760
- Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both numeric strings and have the same length.
761
-
762
- @example
763
- ```
764
- SameLengthPositiveNumericStringGt<'50', '10'>;
765
- //=> true
766
-
767
- SameLengthPositiveNumericStringGt<'10', '10'>;
768
- //=> false
769
- ```
770
- */
771
- type SameLengthPositiveNumericStringGt<A extends string, B extends string> = A extends `${infer FirstA}${infer RestA}`
772
- ? B extends `${infer FirstB}${infer RestB}`
773
- ? FirstA extends FirstB
774
- ? SameLengthPositiveNumericStringGt<RestA, RestB>
775
- : PositiveNumericCharacterGt<FirstA, FirstB>
776
- : never
777
- : false;
778
-
779
- type NumericString = '0123456789';
780
-
781
- /**
782
- Returns a boolean for whether `A` is greater than `B`, where `A` and `B` are both positive numeric strings.
783
-
784
- @example
785
- ```
786
- PositiveNumericStringGt<'500', '1'>;
787
- //=> true
788
-
789
- PositiveNumericStringGt<'1', '1'>;
790
- //=> false
791
-
792
- PositiveNumericStringGt<'1', '500'>;
793
- //=> false
794
- ```
795
- */
796
- type PositiveNumericStringGt<A extends string, B extends string> = A extends B
797
- ? false
798
- : [BuildTuple<StringLength<A>, 0>, BuildTuple<StringLength<B>, 0>] extends infer R extends [readonly unknown[], readonly unknown[]]
799
- ? R[0] extends [...R[1], ...infer Remain extends readonly unknown[]]
800
- ? 0 extends Remain['length']
801
- ? SameLengthPositiveNumericStringGt<A, B>
802
- : true
803
- : false
804
- : never;
805
-
806
- /**
807
- Returns a boolean for whether `A` represents a number greater than `B`, where `A` and `B` are both positive numeric characters.
808
-
809
- @example
810
- ```
811
- PositiveNumericCharacterGt<'5', '1'>;
812
- //=> true
813
-
814
- PositiveNumericCharacterGt<'1', '1'>;
815
- //=> false
816
- ```
817
- */
818
- type PositiveNumericCharacterGt<A extends string, B extends string> = NumericString extends `${infer HeadA}${A}${infer TailA}`
819
- ? NumericString extends `${infer HeadB}${B}${infer TailB}`
820
- ? HeadA extends `${HeadB}${infer _}${infer __}`
821
- ? true
822
- : false
823
- : never
824
- : never;
825
-
826
- /**
827
- Get the exact version of the given `Key` in the given object `T`.
828
-
829
- Use-case: You known that a number key (e.g. 10) is in an object, but you don't know how it is defined in the object, as a string or as a number (e.g. 10 or '10'). You can use this type to get the exact version of the key. See the example.
830
-
831
- @example
832
- ```
833
- type Object = {
834
- 0: number;
835
- '1': string;
836
- };
837
-
838
- type Key1 = ExactKey<Object, '0'>;
839
- //=> 0
840
- type Key2 = ExactKey<Object, 0>;
841
- //=> 0
842
-
843
- type Key3 = ExactKey<Object, '1'>;
844
- //=> '1'
845
- type Key4 = ExactKey<Object, 1>;
846
- //=> '1'
847
- ```
848
-
849
- @category Object
850
- */
851
- type ExactKey<T extends object, Key extends PropertyKey> =
852
- Key extends keyof T
853
- ? Key
854
- : ToString<Key> extends keyof T
855
- ? ToString<Key>
856
- : Key extends `${infer NumberKey extends number}`
857
- ? NumberKey extends keyof T
858
- ? NumberKey
859
- : never
860
- : never;
861
-
862
- /**
863
- Returns the absolute value of a given value.
864
-
865
- @example
866
- ```
867
- NumberAbsolute<-1>;
868
- //=> 1
869
-
870
- NumberAbsolute<1>;
871
- //=> 1
872
-
873
- NumberAbsolute<NegativeInfinity>
874
- //=> PositiveInfinity
875
- ```
876
- */
877
- type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
878
-
879
- /**
880
- Check whether the given type is a number or a number string.
881
-
882
- Supports floating-point as a string.
883
-
884
- @example
885
- ```
886
- type A = IsNumberLike<'1'>;
887
- //=> true
888
-
889
- type B = IsNumberLike<'-1.1'>;
890
- //=> true
891
-
892
- type C = IsNumberLike<1>;
893
- //=> true
894
-
895
- type D = IsNumberLike<'a'>;
896
- //=> false
897
- */
898
- type IsNumberLike<N> =
899
- N extends number ? true
900
- : N extends `${number}`
901
- ? true
902
- : N extends `${number}.${number}`
903
- ? true
904
- : false;
905
-
906
- /**
907
- Returns the minimum number in the given union of numbers.
908
-
909
- Note: Just supports numbers from 0 to 999.
910
-
911
- @example
912
- ```
913
- type A = UnionMin<3 | 1 | 2>;
914
- //=> 1
915
- ```
916
- */
917
- type UnionMin<N extends number> = InternalUnionMin<N>;
918
-
919
- /**
920
- The actual implementation of `UnionMin`. It's private because it has some arguments that don't need to be exposed.
921
- */
922
- type InternalUnionMin<N extends number, T extends UnknownArray = []> =
923
- T['length'] extends N
924
- ? T['length']
925
- : InternalUnionMin<N, [...T, unknown]>;
926
-
927
- /**
928
- Returns the maximum number in the given union of numbers.
929
-
930
- Note: Just supports numbers from 0 to 999.
931
-
932
- @example
933
- ```
934
- type A = UnionMax<1 | 3 | 2>;
935
- //=> 3
936
- ```
937
- */
938
- type UnionMax<N extends number> = InternalUnionMax<N>;
939
-
940
- /**
941
- The actual implementation of `UnionMax`. It's private because it has some arguments that don't need to be exposed.
942
- */
943
- type InternalUnionMax<N extends number, T extends UnknownArray = []> =
944
- IsNever<N> extends true
945
- ? T['length']
946
- : T['length'] extends N
947
- ? InternalUnionMax<Exclude<N, T['length']>, T>
948
- : InternalUnionMax<N, [...T, unknown]>;
949
-
950
- /**
951
- Matches any primitive, `void`, `Date`, or `RegExp` value.
952
- */
953
- type BuiltIns = Primitive | void | Date | RegExp;
954
-
955
- /**
956
- Matches non-recursive types.
957
- */
958
- type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
959
-
960
- /**
961
- Create an object type with the given key `<Key>` and value `<Value>`.
962
-
963
- It will copy the prefix and optional status of the same key from the given object `CopiedFrom` into the result.
964
-
965
- @example
966
- ```
967
- type A = BuildObject<'a', string>;
968
- //=> {a: string}
969
-
970
- // Copy `readonly` and `?` from the key `a` of `{readonly a?: any}`
971
- type B = BuildObject<'a', string, {readonly a?: any}>;
972
- //=> {readonly a?: string}
973
- ```
974
- */
975
- type BuildObject<Key extends PropertyKey, Value, CopiedFrom extends object = {}> =
976
- Key extends keyof CopiedFrom
977
- ? Pick<{[_ in keyof CopiedFrom]: Value}, Key>
978
- : Key extends `${infer NumberKey extends number}`
979
- ? NumberKey extends keyof CopiedFrom
980
- ? Pick<{[_ in keyof CopiedFrom]: Value}, NumberKey>
981
- : {[_ in Key]: Value}
982
- : {[_ in Key]: Value};
983
-
984
- /**
985
- Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
986
-
987
- It creates a type-safe way to access the member type of `unknown` type.
988
- */
989
- type ObjectValue<T, K> =
990
- K extends keyof T
991
- ? T[K]
992
- : ToString<K> extends keyof T
993
- ? T[ToString<K>]
994
- : K extends `${infer NumberK extends number}`
995
- ? NumberK extends keyof T
996
- ? T[NumberK]
997
- : never
998
- : never;
999
-
1000
- /**
1001
- Deeply simplifies an object type.
1002
-
1003
- You can exclude certain types from being simplified by providing them in the second generic `ExcludeType`.
1004
-
1005
- Useful to flatten the type output to improve type hints shown in editors.
1006
-
1007
- @example
1008
- ```
1009
- import type {SimplifyDeep} from 'type-fest';
1010
-
1011
- type PositionX = {
1012
- left: number;
1013
- right: number;
1014
- };
1015
-
1016
- type PositionY = {
1017
- top: number;
1018
- bottom: number;
1019
- };
1020
-
1021
- type Properties1 = {
1022
- height: number;
1023
- position: PositionY;
1024
- };
1025
-
1026
- type Properties2 = {
1027
- width: number;
1028
- position: PositionX;
1029
- };
1030
-
1031
- type Properties = Properties1 & Properties2;
1032
- // In your editor, hovering over `Props` will show the following:
1033
- //
1034
- // type Properties = Properties1 & Properties2;
1035
-
1036
- type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2>;
1037
- // But if wrapped in SimplifyDeep, hovering over `SimplifyDeepProperties` will show a flattened object with all the properties:
1038
- //
1039
- // SimplifyDeepProperties = {
1040
- // height: number;
1041
- // width: number;
1042
- // position: {
1043
- // top: number;
1044
- // bottom: number;
1045
- // left: number;
1046
- // right: number;
1047
- // };
1048
- // };
1049
- ```
1050
-
1051
- @example
1052
- ```
1053
- import type {SimplifyDeep} from 'type-fest';
1054
-
1055
- // A complex type that you don't want or need to simplify
1056
- type ComplexType = {
1057
- a: string;
1058
- b: 'b';
1059
- c: number;
1060
- ...
1061
- };
1062
-
1063
- type PositionX = {
1064
- left: number;
1065
- right: number;
1066
- };
1067
-
1068
- type PositionY = {
1069
- top: number;
1070
- bottom: number;
1071
- };
1072
-
1073
- // You want to simplify all other types
1074
- type Properties1 = {
1075
- height: number;
1076
- position: PositionY;
1077
- foo: ComplexType;
1078
- };
1079
-
1080
- type Properties2 = {
1081
- width: number;
1082
- position: PositionX;
1083
- foo: ComplexType;
1084
- };
1085
-
1086
- type SimplifyDeepProperties = SimplifyDeep<Properties1 & Properties2, ComplexType>;
1087
- // If wrapped in `SimplifyDeep` and set `ComplexType` to exclude, hovering over `SimplifyDeepProperties` will
1088
- // show a flattened object with all the properties except `ComplexType`:
1089
- //
1090
- // SimplifyDeepProperties = {
1091
- // height: number;
1092
- // width: number;
1093
- // position: {
1094
- // top: number;
1095
- // bottom: number;
1096
- // left: number;
1097
- // right: number;
1098
- // };
1099
- // foo: ComplexType;
1100
- // };
1101
- ```
1102
-
1103
- @see Simplify
1104
- @category Object
1105
- */
1106
- type SimplifyDeep<Type, ExcludeType = never> =
1107
- ConditionalSimplifyDeep<
1108
- Type,
1109
- ExcludeType | NonRecursiveType | Set<unknown> | Map<unknown, unknown>,
1110
- object
1111
- >;
1112
-
1113
- /**
1114
- Returns the sum of two numbers.
1115
-
1116
- Note:
1117
- - A or B can only support `-999` ~ `999`.
1118
- - A and B can only be small integers, less than 1000.
1119
- - If the result is negative, you can only get `number`.
1120
-
1121
- @example
1122
- ```
1123
- import type {Sum} from 'type-fest';
1124
-
1125
- Sum<111, 222>;
1126
- //=> 333
1127
-
1128
- Sum<-111, 222>;
1129
- //=> 111
1130
-
1131
- Sum<111, -222>;
1132
- //=> number
1133
-
1134
- Sum<PositiveInfinity, -9999>;
1135
- //=> PositiveInfinity
1136
-
1137
- Sum<PositiveInfinity, NegativeInfinity>;
1138
- //=> number
1139
- ```
1140
-
1141
- @category Numeric
1142
- */
1143
- // TODO: Support big integer and negative number.
1144
- type Sum<A extends number, B extends number> = number extends A | B
1145
- ? number
1146
- : [
1147
- IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
1148
- IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
1149
- ] extends infer R extends [boolean, boolean, boolean, boolean]
1150
- ? Or<
1151
- And<IsEqual<R[0], true>, IsEqual<R[3], false>>,
1152
- And<IsEqual<R[2], true>, IsEqual<R[1], false>>
1153
- > extends true
1154
- ? PositiveInfinity
1155
- : Or<
1156
- And<IsEqual<R[1], true>, IsEqual<R[2], false>>,
1157
- And<IsEqual<R[3], true>, IsEqual<R[0], false>>
1158
- > extends true
1159
- ? NegativeInfinity
1160
- : true extends R[number]
1161
- ? number
1162
- : ([IsNegative<A>, IsNegative<B>] extends infer R
1163
- ? [false, false] extends R
1164
- ? [...BuildTuple<A>, ...BuildTuple<B>]['length']
1165
- : [true, true] extends R
1166
- ? number
1167
- : TupleMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_
1168
- ? TupleMin<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Min_ extends number
1169
- ? Max_ extends A | B
1170
- ? Subtract<Max_, Min_>
1171
- : number
1172
- : never
1173
- : never
1174
- : never) & number
1175
- : never;
1176
-
1177
- /**
1178
- Returns the difference between two numbers.
1179
-
1180
- Note:
1181
- - A or B can only support `-999` ~ `999`.
1182
- - If the result is negative, you can only get `number`.
1183
-
1184
- @example
1185
- ```
1186
- import type {Subtract} from 'type-fest';
1187
-
1188
- Subtract<333, 222>;
1189
- //=> 111
1190
-
1191
- Subtract<111, -222>;
1192
- //=> 333
1193
-
1194
- Subtract<-111, 222>;
1195
- //=> number
1196
-
1197
- Subtract<PositiveInfinity, 9999>;
1198
- //=> PositiveInfinity
1199
-
1200
- Subtract<PositiveInfinity, PositiveInfinity>;
1201
- //=> number
1202
- ```
1203
-
1204
- @category Numeric
1205
- */
1206
- // TODO: Support big integer and negative number.
1207
- type Subtract<A extends number, B extends number> = number extends A | B
1208
- ? number
1209
- : [
1210
- IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
1211
- IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
1212
- ] extends infer R extends [boolean, boolean, boolean, boolean]
1213
- ? Or<
1214
- And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
1215
- And<IsEqual<R[3], true>, IsEqual<R[1], false>>
1216
- > extends true
1217
- ? PositiveInfinity
1218
- : Or<
1219
- And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
1220
- And<IsEqual<R[2], true>, IsEqual<R[0], false>>
1221
- > extends true
1222
- ? NegativeInfinity
1223
- : true extends R[number]
1224
- ? number
1225
- : [IsNegative<A>, IsNegative<B>] extends infer R
1226
- ? [false, false] extends R
1227
- ? BuildTuple<A> extends infer R
1228
- ? R extends [...BuildTuple<B>, ...infer R]
1229
- ? R['length']
1230
- : number
1231
- : never
1232
- : LessThan<A, B> extends true
1233
- ? number
1234
- : [false, true] extends R
1235
- ? Sum<A, NumberAbsolute<B>>
1236
- : Subtract<NumberAbsolute<B>, NumberAbsolute<A>>
1237
- : never
1238
- : never;
1239
-
1240
- /**
1241
- Paths options.
1242
-
1243
- @see {@link Paths}
1244
- */
1245
- type PathsOptions = {
1246
- /**
1247
- The maximum depth to recurse when searching for paths.
1248
-
1249
- @default 10
1250
- */
1251
- maxRecursionDepth?: number;
1252
-
1253
- /**
1254
- Use bracket notation for array indices and numeric object keys.
1255
-
1256
- @default false
1257
-
1258
- @example
1259
- ```
1260
- type ArrayExample = {
1261
- array: ['foo'];
1262
- };
1263
-
1264
- type A = Paths<ArrayExample, {bracketNotation: false}>;
1265
- //=> 'array' | 'array.0'
1266
-
1267
- type B = Paths<ArrayExample, {bracketNotation: true}>;
1268
- //=> 'array' | 'array[0]'
1269
- ```
1270
-
1271
- @example
1272
- ```
1273
- type NumberKeyExample = {
1274
- 1: ['foo'];
1275
- };
1276
-
1277
- type A = Paths<NumberKeyExample, {bracketNotation: false}>;
1278
- //=> 1 | '1' | '1.0'
1279
-
1280
- type B = Paths<NumberKeyExample, {bracketNotation: true}>;
1281
- //=> '[1]' | '[1][0]'
1282
- ```
1283
- */
1284
- bracketNotation?: boolean;
1285
- };
1286
-
1287
- type DefaultPathsOptions = {
1288
- maxRecursionDepth: 10;
1289
- bracketNotation: false;
1290
- };
1291
-
1292
- /**
1293
- Generate a union of all possible paths to properties in the given object.
1294
-
1295
- It also works with arrays.
1296
-
1297
- Use-case: You want a type-safe way to access deeply nested properties in an object.
1298
-
1299
- @example
1300
- ```
1301
- import type {Paths} from 'type-fest';
1302
-
1303
- type Project = {
1304
- filename: string;
1305
- listA: string[];
1306
- listB: [{filename: string}];
1307
- folder: {
1308
- subfolder: {
1309
- filename: string;
1310
- };
1311
- };
1312
- };
1313
-
1314
- type ProjectPaths = Paths<Project>;
1315
- //=> 'filename' | 'listA' | 'listB' | 'folder' | `listA.${number}` | 'listB.0' | 'listB.0.filename' | 'folder.subfolder' | 'folder.subfolder.filename'
1316
-
1317
- declare function open<Path extends ProjectPaths>(path: Path): void;
1318
-
1319
- open('filename'); // Pass
1320
- open('folder.subfolder'); // Pass
1321
- open('folder.subfolder.filename'); // Pass
1322
- open('foo'); // TypeError
1323
-
1324
- // Also works with arrays
1325
- open('listA.1'); // Pass
1326
- open('listB.0'); // Pass
1327
- open('listB.1'); // TypeError. Because listB only has one element.
1328
- ```
1329
-
1330
- @category Object
1331
- @category Array
1332
- */
1333
- type Paths<T, Options extends PathsOptions = {}> = _Paths<T, {
1334
- // Set default maxRecursionDepth to 10
1335
- maxRecursionDepth: Options['maxRecursionDepth'] extends number ? Options['maxRecursionDepth'] : DefaultPathsOptions['maxRecursionDepth'];
1336
- // Set default bracketNotation to false
1337
- bracketNotation: Options['bracketNotation'] extends boolean ? Options['bracketNotation'] : DefaultPathsOptions['bracketNotation'];
1338
- }>;
1339
-
1340
- type _Paths<T, Options extends Required<PathsOptions>> =
1341
- T extends NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
1342
- ? never
1343
- : IsAny<T> extends true
1344
- ? never
1345
- : T extends UnknownArray
1346
- ? number extends T['length']
1347
- // We need to handle the fixed and non-fixed index part of the array separately.
1348
- ? InternalPaths<StaticPartOfArray<T>, Options>
1349
- | InternalPaths<Array<VariablePartOfArray<T>[number]>, Options>
1350
- : InternalPaths<T, Options>
1351
- : T extends object
1352
- ? InternalPaths<T, Options>
1353
- : never;
1354
-
1355
- type InternalPaths<T, Options extends Required<PathsOptions>> =
1356
- Options['maxRecursionDepth'] extends infer MaxDepth extends number
1357
- ? Required<T> extends infer T
1358
- ? T extends EmptyObject | readonly []
1359
- ? never
1360
- : {
1361
- [Key in keyof T]:
1362
- Key extends string | number // Limit `Key` to string or number.
1363
- ? (
1364
- Options['bracketNotation'] extends true
1365
- ? IsNumberLike<Key> extends true
1366
- ? `[${Key}]`
1367
- : (Key | ToString<Key>)
1368
- : never
1369
- |
1370
- Options['bracketNotation'] extends false
1371
- // If `Key` is a number, return `Key | `${Key}``, because both `array[0]` and `array['0']` work.
1372
- ? (Key | ToString<Key>)
1373
- : never
1374
- ) extends infer TranformedKey extends string | number ?
1375
- // 1. If style is 'a[0].b' and 'Key' is a numberlike value like 3 or '3', transform 'Key' to `[${Key}]`, else to `${Key}` | Key
1376
- // 2. If style is 'a.0.b', transform 'Key' to `${Key}` | Key
1377
- | TranformedKey
1378
- | (
1379
- // Recursively generate paths for the current key
1380
- GreaterThan<MaxDepth, 0> extends true // Limit the depth to prevent infinite recursion
1381
- ? _Paths<T[Key], {bracketNotation: Options['bracketNotation']; maxRecursionDepth: Subtract<MaxDepth, 1>}> extends infer SubPath
1382
- ? SubPath extends string | number
1383
- ? (
1384
- Options['bracketNotation'] extends true
1385
- ? SubPath extends `[${any}]` | `[${any}]${string}`
1386
- ? `${TranformedKey}${SubPath}` // If next node is number key like `[3]`, no need to add `.` before it.
1387
- : `${TranformedKey}.${SubPath}`
1388
- : never
1389
- ) | (
1390
- Options['bracketNotation'] extends false
1391
- ? `${TranformedKey}.${SubPath}`
1392
- : never
1393
- )
1394
- : never
1395
- : never
1396
- : never
1397
- )
1398
- : never
1399
- : never
1400
- }[keyof T & (T extends UnknownArray ? number : unknown)]
1401
- : never
1402
- : never;
1403
-
1404
- /**
1405
- Pick properties from a deeply-nested object.
1406
-
1407
- It supports recursing into arrays.
1408
-
1409
- Use-case: Distill complex objects down to the components you need to target.
1410
-
1411
- @example
1412
- ```
1413
- import type {PickDeep, PartialDeep} from 'type-fest';
1414
-
1415
- type Configuration = {
1416
- userConfig: {
1417
- name: string;
1418
- age: number;
1419
- address: [
1420
- {
1421
- city1: string;
1422
- street1: string;
1423
- },
1424
- {
1425
- city2: string;
1426
- street2: string;
1427
- }
1428
- ]
1429
- };
1430
- otherConfig: any;
1431
- };
1432
-
1433
- type NameConfig = PickDeep<Configuration, 'userConfig.name'>;
1434
- // type NameConfig = {
1435
- // userConfig: {
1436
- // name: string;
1437
- // }
1438
- // };
1439
-
1440
- // Supports optional properties
1441
- type User = PickDeep<PartialDeep<Configuration>, 'userConfig.name' | 'userConfig.age'>;
1442
- // type User = {
1443
- // userConfig?: {
1444
- // name?: string;
1445
- // age?: number;
1446
- // };
1447
- // };
1448
-
1449
- // Supports array
1450
- type AddressConfig = PickDeep<Configuration, 'userConfig.address.0'>;
1451
- // type AddressConfig = {
1452
- // userConfig: {
1453
- // address: [{
1454
- // city1: string;
1455
- // street1: string;
1456
- // }];
1457
- // };
1458
- // }
1459
-
1460
- // Supports recurse into array
1461
- type Street = PickDeep<Configuration, 'userConfig.address.1.street2'>;
1462
- // type Street = {
1463
- // userConfig: {
1464
- // address: [
1465
- // unknown,
1466
- // {street2: string}
1467
- // ];
1468
- // };
1469
- // }
1470
- ```
1471
-
1472
- @category Object
1473
- @category Array
1474
- */
1475
- type PickDeep<T, PathUnion extends Paths<T>> =
1476
- T extends NonRecursiveType
1477
- ? never
1478
- : T extends UnknownArray
1479
- ? UnionToIntersection<{
1480
- [P in PathUnion]: InternalPickDeep<T, P>;
1481
- }[PathUnion]
1482
- >
1483
- : T extends object
1484
- ? Simplify<UnionToIntersection<{
1485
- [P in PathUnion]: InternalPickDeep<T, P>;
1486
- }[PathUnion]>>
1487
- : never;
1488
-
1489
- /**
1490
- Pick an object/array from the given object/array by one path.
1491
- */
1492
- type InternalPickDeep<T, Path extends string | number> =
1493
- T extends NonRecursiveType
1494
- ? never
1495
- : T extends UnknownArray ? PickDeepArray<T, Path>
1496
- : T extends object ? Simplify<PickDeepObject<T, Path>>
1497
- : never;
1498
-
1499
- /**
1500
- Pick an object from the given object by one path.
1501
- */
1502
- type PickDeepObject<RecordType extends object, P extends string | number> =
1503
- P extends `${infer RecordKeyInPath}.${infer SubPath}`
1504
- ? ObjectValue<RecordType, RecordKeyInPath> extends infer ObjectV
1505
- ? IsNever<ObjectV> extends false
1506
- ? BuildObject<RecordKeyInPath, InternalPickDeep<NonNullable<ObjectV>, SubPath>, RecordType>
1507
- : never
1508
- : never
1509
- : ObjectValue<RecordType, P> extends infer ObjectV
1510
- ? IsNever<ObjectV> extends false
1511
- ? BuildObject<P, ObjectV, RecordType>
1512
- : never
1513
- : never;
1514
-
1515
- /**
1516
- Pick an array from the given array by one path.
1517
- */
1518
- type PickDeepArray<ArrayType extends UnknownArray, P extends string | number> =
1519
- // Handle paths that are `${number}.${string}`
1520
- P extends `${infer ArrayIndex extends number}.${infer SubPath}`
1521
- // When `ArrayIndex` is equal to `number`
1522
- ? number extends ArrayIndex
1523
- ? ArrayType extends unknown[]
1524
- ? Array<InternalPickDeep<NonNullable<ArrayType[number]>, SubPath>>
1525
- : ArrayType extends readonly unknown[]
1526
- ? ReadonlyArray<InternalPickDeep<NonNullable<ArrayType[number]>, SubPath>>
1527
- : never
1528
- // When `ArrayIndex` is a number literal
1529
- : ArrayType extends unknown[]
1530
- ? [...BuildTuple<ArrayIndex>, InternalPickDeep<NonNullable<ArrayType[ArrayIndex]>, SubPath>]
1531
- : ArrayType extends readonly unknown[]
1532
- ? readonly [...BuildTuple<ArrayIndex>, InternalPickDeep<NonNullable<ArrayType[ArrayIndex]>, SubPath>]
1533
- : never
1534
- // When the path is equal to `number`
1535
- : P extends `${infer ArrayIndex extends number}`
1536
- // When `ArrayIndex` is `number`
1537
- ? number extends ArrayIndex
1538
- ? ArrayType
1539
- // When `ArrayIndex` is a number literal
1540
- : ArrayType extends unknown[]
1541
- ? [...BuildTuple<ArrayIndex>, ArrayType[ArrayIndex]]
1542
- : ArrayType extends readonly unknown[]
1543
- ? readonly [...BuildTuple<ArrayIndex>, ArrayType[ArrayIndex]]
1544
- : never
1545
- : never;
1546
-
1547
- /**
1548
- The implementation of `SplitArrayByIndex` for fixed length arrays.
1549
- */
1550
- type SplitFixedArrayByIndex<T extends UnknownArray, SplitIndex extends number> =
1551
- SplitIndex extends 0
1552
- ? [[], T]
1553
- : T extends readonly [...BuildTuple<SplitIndex>, ...infer V]
1554
- ? T extends readonly [...infer U, ...V]
1555
- ? [U, V]
1556
- : [never, never]
1557
- : [never, never];
1558
-
1559
- /**
1560
- The implementation of `SplitArrayByIndex` for variable length arrays.
1561
- */
1562
- type SplitVariableArrayByIndex<T extends UnknownArray,
1563
- SplitIndex extends number,
1564
- T1 = Subtract<SplitIndex, StaticPartOfArray<T>['length']>,
1565
- T2 = T1 extends number ? BuildTuple<T1, VariablePartOfArray<T>[number]> : [],
1566
- > =
1567
- SplitIndex extends 0
1568
- ? [[], T]
1569
- : GreaterThanOrEqual<StaticPartOfArray<T>['length'], SplitIndex> extends true
1570
- ? [
1571
- SplitFixedArrayByIndex<StaticPartOfArray<T>, SplitIndex>[0],
1572
- [
1573
- ...SplitFixedArrayByIndex<StaticPartOfArray<T>, SplitIndex>[1],
1574
- ...VariablePartOfArray<T>,
1575
- ],
1576
- ]
1577
- : [
1578
- [
1579
- ...StaticPartOfArray<T>,
1580
- ...(T2 extends UnknownArray ? T2 : []),
1581
- ],
1582
- VariablePartOfArray<T>,
1583
- ];
1584
-
1585
- /**
1586
- Split the given array `T` by the given `SplitIndex`.
1587
-
1588
- @example
1589
- ```
1590
- type A = SplitArrayByIndex<[1, 2, 3, 4], 2>;
1591
- // type A = [[1, 2], [3, 4]];
1592
-
1593
- type B = SplitArrayByIndex<[1, 2, 3, 4], 0>;
1594
- // type B = [[], [1, 2, 3, 4]];
1595
- ```
1596
- */
1597
- type SplitArrayByIndex<T extends UnknownArray, SplitIndex extends number> =
1598
- SplitIndex extends 0
1599
- ? [[], T]
1600
- : number extends T['length']
1601
- ? SplitVariableArrayByIndex<T, SplitIndex>
1602
- : SplitFixedArrayByIndex<T, SplitIndex>;
1603
-
1604
- /**
1605
- Creates a new array type by adding or removing elements at a specified index range in the original array.
1606
-
1607
- Use-case: Replace or insert items in an array type.
1608
-
1609
- Like [`Array#splice()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) but for types.
1610
-
1611
- @example
1612
- ```
1613
- type SomeMonths0 = ['January', 'April', 'June'];
1614
- type Mouths0 = ArraySplice<SomeMonths0, 1, 0, ['Feb', 'March']>;
1615
- //=> type Mouths0 = ['January', 'Feb', 'March', 'April', 'June'];
1616
-
1617
- type SomeMonths1 = ['January', 'April', 'June'];
1618
- type Mouths1 = ArraySplice<SomeMonths1, 1, 1>;
1619
- //=> type Mouths1 = ['January', 'June'];
1620
-
1621
- type SomeMonths2 = ['January', 'Foo', 'April'];
1622
- type Mouths2 = ArraySplice<SomeMonths2, 1, 1, ['Feb', 'March']>;
1623
- //=> type Mouths2 = ['January', 'Feb', 'March', 'April'];
1624
- ```
1625
-
1626
- @category Array
1627
- */
1628
- type ArraySplice<
1629
- T extends UnknownArray,
1630
- Start extends number,
1631
- DeleteCount extends number,
1632
- Items extends UnknownArray = [],
1633
- > =
1634
- SplitArrayByIndex<T, Start> extends [infer U extends UnknownArray, infer V extends UnknownArray]
1635
- ? SplitArrayByIndex<V, DeleteCount> extends [infer _Deleted extends UnknownArray, infer X extends UnknownArray]
1636
- ? [...U, ...Items, ...X]
1637
- : never // Should never happen
1638
- : never; // Should never happen
1639
-
1640
- type LiteralStringUnion<T> = LiteralUnion<T, string>;
1641
-
1642
- /**
1643
- Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
1644
-
1645
- Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.
1646
-
1647
- This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore.
1648
-
1649
- @example
1650
- ```
1651
- import type {LiteralUnion} from 'type-fest';
1652
-
1653
- // Before
1654
-
1655
- type Pet = 'dog' | 'cat' | string;
1656
-
1657
- const pet: Pet = '';
1658
- // Start typing in your TypeScript-enabled IDE.
1659
- // You **will not** get auto-completion for `dog` and `cat` literals.
1660
-
1661
- // After
1662
-
1663
- type Pet2 = LiteralUnion<'dog' | 'cat', string>;
1664
-
1665
- const pet: Pet2 = '';
1666
- // You **will** get auto-completion for `dog` and `cat` literals.
1667
- ```
1668
-
1669
- @category Type
1670
- */
1671
- type LiteralUnion<
1672
- LiteralType,
1673
- BaseType extends Primitive,
1674
- > = LiteralType | (BaseType & Record<never, never>);
1675
-
1676
- /**
1677
- SharedUnionFieldsDeep options.
1678
-
1679
- @see {@link SharedUnionFieldsDeep}
1680
- */
1681
- type SharedUnionFieldsDeepOptions = {
1682
- /**
1683
- When set to true, this option impacts each element within arrays or tuples. If all union values are arrays or tuples, it constructs an array of the shortest possible length, ensuring every element exists in the union array.
1684
-
1685
- @default false
1686
- */
1687
- recurseIntoArrays?: boolean;
1688
- };
1689
-
1690
- /**
1691
- Create a type with shared fields from a union of object types, deeply traversing nested structures.
1692
-
1693
- Use the {@link SharedUnionFieldsDeepOptions `Options`} to specify the behavior for arrays.
1694
-
1695
- Use-cases:
1696
- - You want a safe object type where each key exists in the union object.
1697
- - You want to focus on the common fields of the union type and don't want to have to care about the other fields.
1698
-
1699
- @example
1700
- ```
1701
- import type {SharedUnionFieldsDeep} from 'type-fest';
1702
-
1703
- type Cat = {
1704
- info: {
1705
- name: string;
1706
- type: 'cat';
1707
- catType: string;
1708
- };
1709
- };
1710
-
1711
- type Dog = {
1712
- info: {
1713
- name: string;
1714
- type: 'dog';
1715
- dogType: string;
1716
- };
1717
- };
1718
-
1719
- function displayPetInfo(petInfo: (Cat | Dog)['info']) {
1720
- // typeof petInfo =>
1721
- // {
1722
- // name: string;
1723
- // type: 'cat';
1724
- // catType: string; // Needn't care about this field, because it's not a common pet info field.
1725
- // } | {
1726
- // name: string;
1727
- // type: 'dog';
1728
- // dogType: string; // Needn't care about this field, because it's not a common pet info field.
1729
- // }
1730
-
1731
- // petInfo type is complex and have some needless fields
1732
-
1733
- console.log('name: ', petInfo.name);
1734
- console.log('type: ', petInfo.type);
1735
- }
1736
-
1737
- function displayPetInfo(petInfo: SharedUnionFieldsDeep<Cat | Dog>['info']) {
1738
- // typeof petInfo =>
1739
- // {
1740
- // name: string;
1741
- // type: 'cat' | 'dog';
1742
- // }
1743
-
1744
- // petInfo type is simple and clear
1745
-
1746
- console.log('name: ', petInfo.name);
1747
- console.log('type: ', petInfo.type);
1748
- }
1749
- ```
1750
-
1751
- @see SharedUnionFields
1752
-
1753
- @category Object
1754
- @category Union
1755
- */
1756
- type SharedUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions = {recurseIntoArrays: false}> =
1757
- // `Union extends` will convert `Union`
1758
- // to a [distributive conditionaltype](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types).
1759
- // But this is not what we want, so we need to wrap `Union` with `[]` to prevent it.
1760
- [Union] extends [NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>]
1761
- ? Union
1762
- : [Union] extends [UnknownArray]
1763
- ? Options['recurseIntoArrays'] extends true
1764
- ? SetArrayAccess<SharedArrayUnionFieldsDeep<Union, Options>, IsArrayReadonly<Union>>
1765
- : Union
1766
- : [Union] extends [object]
1767
- ? SharedObjectUnionFieldsDeep<Union, Options>
1768
- : Union;
1769
-
1770
- /**
1771
- Same as `SharedUnionFieldsDeep`, but accepts only `object`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
1772
- */
1773
- type SharedObjectUnionFieldsDeep<Union, Options extends SharedUnionFieldsDeepOptions> =
1774
- // `keyof Union` can extract the same key in union type, if there is no same key, return never.
1775
- keyof Union extends infer Keys
1776
- ? IsNever<Keys> extends false
1777
- ? {
1778
- [Key in keyof Union]:
1779
- Union[Key] extends NonRecursiveType
1780
- ? Union[Key]
1781
- // Remove `undefined` from the union to support optional
1782
- // fields, then recover `undefined` if union was already undefined.
1783
- : SharedUnionFieldsDeep<Exclude<Union[Key], undefined>, Options> | (
1784
- undefined extends Required<Union>[Key] ? undefined : never
1785
- )
1786
- }
1787
- : {}
1788
- : Union;
1789
-
1790
- /**
1791
- Same as `SharedUnionFieldsDeep`, but accepts only `UnknownArray`s and as inputs. Internal helper for `SharedUnionFieldsDeep`.
1792
- */
1793
- type SharedArrayUnionFieldsDeep<Union extends UnknownArray, Options extends SharedUnionFieldsDeepOptions> =
1794
- // Restore the readonly modifier of the array.
1795
- SetArrayAccess<
1796
- InternalSharedArrayUnionFieldsDeep<Union, Options>,
1797
- IsArrayReadonly<Union>
1798
- >;
1799
-
1800
- /**
1801
- Internal helper for `SharedArrayUnionFieldsDeep`. Needn't care the `readonly` modifier of arrays.
1802
- */
1803
- type InternalSharedArrayUnionFieldsDeep<
1804
- Union extends UnknownArray,
1805
- Options extends SharedUnionFieldsDeepOptions,
1806
- ResultTuple extends UnknownArray = [],
1807
- > =
1808
- // We should build a minimum possible length tuple where each element in the tuple exists in the union tuple.
1809
- IsNever<TupleLength<Union>> extends true
1810
- // Rule 1: If all the arrays in the union have non-fixed lengths,
1811
- // like `Array<string> | [number, ...string[]]`
1812
- // we should build a tuple that is [the_fixed_parts_of_union, ...the_rest_of_union[]].
1813
- // For example: `InternalSharedArrayUnionFieldsDeep<Array<string> | [number, ...string[]]>`
1814
- // => `[string | number, ...string[]]`.
1815
- ? ResultTuple['length'] extends UnionMax<StaticPartOfArray<Union>['length']>
1816
- ? [
1817
- // The fixed-length part of the tuple.
1818
- ...ResultTuple,
1819
- // The rest of the union.
1820
- // Due to `ResultTuple` is the maximum possible fixed-length part of the tuple,
1821
- // so we can use `StaticPartOfArray` to get the rest of the union.
1822
- ...Array<
1823
- SharedUnionFieldsDeep<VariablePartOfArray<Union>[number], Options>
1824
- >,
1825
- ]
1826
- // Build the fixed-length tuple recursively.
1827
- : InternalSharedArrayUnionFieldsDeep<
1828
- Union, Options,
1829
- [...ResultTuple, SharedUnionFieldsDeep<Union[ResultTuple['length']], Options>]
1830
- >
1831
- // Rule 2: If at least one of the arrays in the union have fixed lengths,
1832
- // like `Array<string> | [number, string]`,
1833
- // we should build a tuple of the smallest possible length to ensure any
1834
- // item in the result tuple exists in the union tuple.
1835
- // For example: `InternalSharedArrayUnionFieldsDeep<Array<string> | [number, string]>`
1836
- // => `[string | number, string]`.
1837
- : ResultTuple['length'] extends UnionMin<TupleLength<Union>>
1838
- ? ResultTuple
1839
- // As above, build tuple recursively.
1840
- : InternalSharedArrayUnionFieldsDeep<
1841
- Union, Options,
1842
- [...ResultTuple, SharedUnionFieldsDeep<Union[ResultTuple['length']], Options>]
1843
- >;
1844
-
1845
- /**
1846
- Omit properties from a deeply-nested object.
1847
-
1848
- It supports recursing into arrays.
1849
-
1850
- It supports removing specific items from an array, replacing each removed item with unknown at the specified index.
1851
-
1852
- Use-case: Remove unneeded parts of complex objects.
1853
-
1854
- Use [`Omit`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys) if you only need one level deep.
1855
-
1856
- @example
1857
- ```
1858
- import type {OmitDeep} from 'type-fest';
1859
-
1860
- type Info = {
1861
- userInfo: {
1862
- name: string;
1863
- uselessInfo: {
1864
- foo: string;
1865
- };
1866
- };
1867
- };
1868
-
1869
- type UsefulInfo = OmitDeep<Info, 'userInfo.uselessInfo'>;
1870
- // type UsefulInfo = {
1871
- // userInfo: {
1872
- // name: string;
1873
- // };
1874
- // };
1875
-
1876
- // Supports removing multiple paths
1877
- type Info1 = {
1878
- userInfo: {
1879
- name: string;
1880
- uselessField: string;
1881
- uselessInfo: {
1882
- foo: string;
1883
- };
1884
- };
1885
- };
1886
-
1887
- type UsefulInfo1 = OmitDeep<Info1, 'userInfo.uselessInfo' | 'userInfo.uselessField'>;
1888
- // type UsefulInfo1 = {
1889
- // userInfo: {
1890
- // name: string;
1891
- // };
1892
- // };
1893
-
1894
- // Supports array
1895
- type A = OmitDeep<[1, 'foo', 2], 1>;
1896
- // type A = [1, unknown, 2];
1897
-
1898
- // Supports recursing into array
1899
-
1900
- type Info1 = {
1901
- address: [
1902
- {
1903
- street: string
1904
- },
1905
- {
1906
- street2: string,
1907
- foo: string
1908
- };
1909
- ];
1910
- }
1911
- type AddressInfo = OmitDeep<Info1, 'address.1.foo'>;
1912
- // type AddressInfo = {
1913
- // address: [
1914
- // {
1915
- // street: string;
1916
- // },
1917
- // {
1918
- // street2: string;
1919
- // };
1920
- // ];
1921
- // };
1922
- ```
1923
-
1924
- @category Object
1925
- @category Array
1926
- */
1927
- type OmitDeep<T, PathUnion extends LiteralUnion<Paths<T>, string>> =
1928
- SimplifyDeep<
1929
- SharedUnionFieldsDeep<
1930
- {[P in PathUnion]: OmitDeepWithOnePath<T, P>}[PathUnion]
1931
- >,
1932
- UnknownArray>;
1933
-
1934
- /**
1935
- Omit one path from the given object/array.
1936
- */
1937
- type OmitDeepWithOnePath<T, Path extends string | number> =
1938
- T extends NonRecursiveType
1939
- ? T
1940
- : T extends UnknownArray ? SetArrayAccess<OmitDeepArrayWithOnePath<T, Path>, IsArrayReadonly<T>>
1941
- : T extends object ? OmitDeepObjectWithOnePath<T, Path>
1942
- : T;
1943
-
1944
- /**
1945
- Omit one path from the given object.
1946
- */
1947
- type OmitDeepObjectWithOnePath<ObjectT extends object, P extends string | number> =
1948
- P extends `${infer RecordKeyInPath}.${infer SubPath}`
1949
- ? {
1950
- [Key in keyof ObjectT]:
1951
- IsEqual<RecordKeyInPath, ToString<Key>> extends true
1952
- ? ExactKey<ObjectT, Key> extends infer RealKey
1953
- ? RealKey extends keyof ObjectT
1954
- ? OmitDeepWithOnePath<ObjectT[RealKey], SubPath>
1955
- : ObjectT[Key]
1956
- : ObjectT[Key]
1957
- : ObjectT[Key]
1958
- }
1959
- : ExactKey<ObjectT, P> extends infer Key
1960
- ? IsNever<Key> extends true
1961
- ? ObjectT
1962
- : Key extends PropertyKey
1963
- ? Omit<ObjectT, Key>
1964
- : ObjectT
1965
- : ObjectT;
1966
-
1967
- /**
1968
- Omit one path from from the given array.
1969
-
1970
- It replaces the item to `unknown` at the given index.
1971
-
1972
- @example
1973
- ```
1974
- type A = OmitDeepArrayWithOnePath<[10, 20, 30, 40], 2>;
1975
- //=> type A = [10, 20, unknown, 40];
1976
- ```
1977
- */
1978
- type OmitDeepArrayWithOnePath<ArrayType extends UnknownArray, P extends string | number> =
1979
- // Handle paths that are `${number}.${string}`
1980
- P extends `${infer ArrayIndex extends number}.${infer SubPath}`
1981
- // If `ArrayIndex` is equal to `number`
1982
- ? number extends ArrayIndex
1983
- ? Array<OmitDeepWithOnePath<NonNullable<ArrayType[number]>, SubPath>>
1984
- // If `ArrayIndex` is a number literal
1985
- : ArraySplice<ArrayType, ArrayIndex, 1, [OmitDeepWithOnePath<NonNullable<ArrayType[ArrayIndex]>, SubPath>]>
1986
- // If the path is equal to `number`
1987
- : P extends `${infer ArrayIndex extends number}`
1988
- // If `ArrayIndex` is `number`
1989
- ? number extends ArrayIndex
1990
- ? []
1991
- // If `ArrayIndex` is a number literal
1992
- : ArraySplice<ArrayType, ArrayIndex, 1, [unknown]>
1993
- : ArrayType;
1994
-
1995
- /**
1996
- Get keys of the given type as strings.
1997
-
1998
- Number keys are converted to strings.
1999
-
2000
- Use-cases:
2001
- - Get string keys from a type which may have number keys.
2002
- - Makes it possible to index using strings retrieved from template types.
2003
-
2004
- @example
2005
- ```
2006
- import type {StringKeyOf} from 'type-fest';
2007
-
2008
- type Foo = {
2009
- 1: number,
2010
- stringKey: string,
2011
- };
2012
-
2013
- type StringKeysOfFoo = StringKeyOf<Foo>;
2014
- //=> '1' | 'stringKey'
2015
- ```
2016
-
2017
- @category Object
2018
- */
2019
- type StringKeyOf<BaseType> = `${Extract<keyof BaseType, string | number>}`;
2020
-
2021
- /**
2022
- Represents an array of strings split using a given character or character set.
2023
-
2024
- Use-case: Defining the return type of a method like `String.prototype.split`.
2025
-
2026
- @example
2027
- ```
2028
- import type {Split} from 'type-fest';
2029
-
2030
- declare function split<S extends string, D extends string>(string: S, separator: D): Split<S, D>;
2031
-
2032
- type Item = 'foo' | 'bar' | 'baz' | 'waldo';
2033
- const items = 'foo,bar,baz,waldo';
2034
- let array: Item[];
2035
-
2036
- array = split(items, ',');
2037
- ```
2038
-
2039
- @category String
2040
- @category Template literal
2041
- */
2042
- type Split<
2043
- S extends string,
2044
- Delimiter extends string,
2045
- > = SplitHelper<S, Delimiter>;
2046
-
2047
- type SplitHelper<
2048
- S extends string,
2049
- Delimiter extends string,
2050
- Accumulator extends string[] = [],
2051
- > = S extends `${infer Head}${Delimiter}${infer Tail}`
2052
- ? SplitHelper<Tail, Delimiter, [...Accumulator, Head]>
2053
- : Delimiter extends ''
2054
- ? Accumulator
2055
- : [...Accumulator, S];
2056
-
2057
- type GetOptions = {
2058
- /**
2059
- Include `undefined` in the return type when accessing properties.
2060
-
2061
- Setting this to `false` is not recommended.
2062
-
2063
- @default true
2064
- */
2065
- strict?: boolean;
2066
- };
2067
-
2068
- /**
2069
- Like the `Get` type but receives an array of strings as a path parameter.
2070
- */
2071
- type GetWithPath<BaseType, Keys, Options extends GetOptions = {}> =
2072
- Keys extends readonly []
2073
- ? BaseType
2074
- : Keys extends readonly [infer Head, ...infer Tail]
2075
- ? GetWithPath<
2076
- PropertyOf<BaseType, Extract<Head, string>, Options>,
2077
- Extract<Tail, string[]>,
2078
- Options
2079
- >
2080
- : never;
2081
-
2082
- /**
2083
- Adds `undefined` to `Type` if `strict` is enabled.
2084
- */
2085
- type Strictify<Type, Options extends GetOptions> =
2086
- Options['strict'] extends false ? Type : (Type | undefined);
2087
-
2088
- /**
2089
- If `Options['strict']` is `true`, includes `undefined` in the returned type when accessing properties on `Record<string, any>`.
2090
-
2091
- Known limitations:
2092
- - Does not include `undefined` in the type on object types with an index signature (for example, `{a: string; [key: string]: string}`).
2093
- */
2094
- type StrictPropertyOf<BaseType, Key extends keyof BaseType, Options extends GetOptions> =
2095
- Record<string, any> extends BaseType
2096
- ? string extends keyof BaseType
2097
- ? Strictify<BaseType[Key], Options> // Record<string, any>
2098
- : BaseType[Key] // Record<'a' | 'b', any> (Records with a string union as keys have required properties)
2099
- : BaseType[Key];
2100
-
2101
- /**
2102
- Splits a dot-prop style path into a tuple comprised of the properties in the path. Handles square-bracket notation.
2103
-
2104
- @example
2105
- ```
2106
- ToPath<'foo.bar.baz'>
2107
- //=> ['foo', 'bar', 'baz']
2108
-
2109
- ToPath<'foo[0].bar.baz'>
2110
- //=> ['foo', '0', 'bar', 'baz']
2111
- ```
2112
- */
2113
- type ToPath<S extends string> = Split<FixPathSquareBrackets<S>, '.'>;
2114
-
2115
- /**
2116
- Replaces square-bracketed dot notation with dots, for example, `foo[0].bar` -> `foo.0.bar`.
2117
- */
2118
- type FixPathSquareBrackets<Path extends string> =
2119
- Path extends `[${infer Head}]${infer Tail}`
2120
- ? Tail extends `[${string}`
2121
- ? `${Head}.${FixPathSquareBrackets<Tail>}`
2122
- : `${Head}${FixPathSquareBrackets<Tail>}`
2123
- : Path extends `${infer Head}[${infer Middle}]${infer Tail}`
2124
- ? `${Head}.${FixPathSquareBrackets<`[${Middle}]${Tail}`>}`
2125
- : Path;
2126
-
2127
- /**
2128
- Returns true if `LongString` is made up out of `Substring` repeated 0 or more times.
2129
-
2130
- @example
2131
- ```
2132
- ConsistsOnlyOf<'aaa', 'a'> //=> true
2133
- ConsistsOnlyOf<'ababab', 'ab'> //=> true
2134
- ConsistsOnlyOf<'aBa', 'a'> //=> false
2135
- ConsistsOnlyOf<'', 'a'> //=> true
2136
- ```
2137
- */
2138
- type ConsistsOnlyOf<LongString extends string, Substring extends string> =
2139
- LongString extends ''
2140
- ? true
2141
- : LongString extends `${Substring}${infer Tail}`
2142
- ? ConsistsOnlyOf<Tail, Substring>
2143
- : false;
2144
-
2145
- /**
2146
- Convert a type which may have number keys to one with string keys, making it possible to index using strings retrieved from template types.
2147
-
2148
- @example
2149
- ```
2150
- type WithNumbers = {foo: string; 0: boolean};
2151
- type WithStrings = WithStringKeys<WithNumbers>;
2152
-
2153
- type WithNumbersKeys = keyof WithNumbers;
2154
- //=> 'foo' | 0
2155
- type WithStringsKeys = keyof WithStrings;
2156
- //=> 'foo' | '0'
2157
- ```
2158
- */
2159
- type WithStringKeys<BaseType> = {
2160
- [Key in StringKeyOf<BaseType>]: UncheckedIndex<BaseType, Key>
2161
- };
2162
-
2163
- /**
2164
- Perform a `T[U]` operation if `T` supports indexing.
2165
- */
2166
- type UncheckedIndex<T, U extends string | number> = [T] extends [Record<string | number, any>] ? T[U] : never;
2167
-
2168
- /**
2169
- Get a property of an object or array. Works when indexing arrays using number-literal-strings, for example, `PropertyOf<number[], '0'> = number`, and when indexing objects with number keys.
2170
-
2171
- Note:
2172
- - Returns `unknown` if `Key` is not a property of `BaseType`, since TypeScript uses structural typing, and it cannot be guaranteed that extra properties unknown to the type system will exist at runtime.
2173
- - Returns `undefined` from nullish values, to match the behaviour of most deep-key libraries like `lodash`, `dot-prop`, etc.
2174
- */
2175
- type PropertyOf<BaseType, Key extends string, Options extends GetOptions = {}> =
2176
- BaseType extends null | undefined
2177
- ? undefined
2178
- : Key extends keyof BaseType
2179
- ? StrictPropertyOf<BaseType, Key, Options>
2180
- // Handle arrays and tuples
2181
- : BaseType extends readonly unknown[]
2182
- ? Key extends `${number}`
2183
- // For arrays with unknown length (regular arrays)
2184
- ? number extends BaseType['length']
2185
- ? Strictify<BaseType[number], Options>
2186
- // For tuples: check if the index is valid
2187
- : Key extends keyof BaseType
2188
- ? Strictify<BaseType[Key & keyof BaseType], Options>
2189
- // Out-of-bounds access for tuples
2190
- : unknown
2191
- // Non-numeric string key for arrays/tuples
2192
- : unknown
2193
- // Handle array-like objects
2194
- : BaseType extends {
2195
- [n: number]: infer Item;
2196
- length: number; // Note: This is needed to avoid being too lax with records types using number keys like `{0: string; 1: boolean}`.
2197
- }
2198
- ? (
2199
- ConsistsOnlyOf<Key, StringDigit> extends true
2200
- ? Strictify<Item, Options>
2201
- : unknown
2202
- )
2203
- : Key extends keyof WithStringKeys<BaseType>
2204
- ? StrictPropertyOf<WithStringKeys<BaseType>, Key, Options>
2205
- : unknown;
2206
-
2207
- // This works by first splitting the path based on `.` and `[...]` characters into a tuple of string keys. Then it recursively uses the head key to get the next property of the current object, until there are no keys left. Number keys extract the item type from arrays, or are converted to strings to extract types from tuples and dictionaries with number keys.
2208
- /**
2209
- Get a deeply-nested property from an object using a key path, like Lodash's `.get()` function.
2210
-
2211
- Use-case: Retrieve a property from deep inside an API response or some other complex object.
2212
-
2213
- @example
2214
- ```
2215
- import type {Get} from 'type-fest';
2216
- import * as lodash from 'lodash';
2217
-
2218
- const get = <BaseType, Path extends string | readonly string[]>(object: BaseType, path: Path): Get<BaseType, Path> =>
2219
- lodash.get(object, path);
2220
-
2221
- interface ApiResponse {
2222
- hits: {
2223
- hits: Array<{
2224
- _id: string
2225
- _source: {
2226
- name: Array<{
2227
- given: string[]
2228
- family: string
2229
- }>
2230
- birthDate: string
2231
- }
2232
- }>
2233
- }
2234
- }
2235
-
2236
- const getName = (apiResponse: ApiResponse) =>
2237
- get(apiResponse, 'hits.hits[0]._source.name');
2238
- //=> Array<{given: string[]; family: string}> | undefined
2239
-
2240
- // Path also supports a readonly array of strings
2241
- const getNameWithPathArray = (apiResponse: ApiResponse) =>
2242
- get(apiResponse, ['hits','hits', '0', '_source', 'name'] as const);
2243
- //=> Array<{given: string[]; family: string}> | undefined
2244
-
2245
- // Non-strict mode:
2246
- Get<string[], '3', {strict: false}> //=> string
2247
- Get<Record<string, string>, 'foo', {strict: true}> // => string
2248
- ```
2249
-
2250
- @category Object
2251
- @category Array
2252
- @category Template literal
2253
- */
2254
- type Get<
2255
- BaseType,
2256
- Path extends
2257
- | readonly string[]
2258
- | LiteralStringUnion<ToString<Paths<BaseType, {bracketNotation: false; maxRecursionDepth: 2}> | Paths<BaseType, {bracketNotation: true; maxRecursionDepth: 2}>>>,
2259
- Options extends GetOptions = {}> =
2260
- GetWithPath<BaseType, Path extends string ? ToPath<Path> : Path, Options>;
2261
-
2262
- declare const omit: <T extends { [key in string]: unknown; }, K extends string>(object: T, keys: Paths<T>[]) => OmitDeep<T, K>;
2263
-
2264
- declare const pick: <T extends { [key in string]: unknown; }, K extends Paths<T>>(object: T, keys: Paths<T>[]) => PickDeep<T, K>;
2265
-
2266
- interface DeeksOptions {
2267
- /** @default false */
2268
- arrayIndexesAsKeys?: boolean;
2269
- /** @default true */
2270
- expandNestedObjects?: boolean;
2271
- /** @default false */
2272
- expandArrayObjects?: boolean;
2273
- /** @default false */
2274
- ignoreEmptyArraysWhenExpanding?: boolean;
2275
- /** @default false */
2276
- escapeNestedDots?: boolean;
2277
- /** @default false */
2278
- ignoreEmptyArrays?: boolean;
2279
- }
2280
-
2281
- /**
2282
- * Return the deep keys list for a single document
2283
- * @param object
2284
- * @param options
2285
- * @returns {Array}
2286
- */
2287
- declare function deepKeys(object: object, options?: DeeksOptions): string[];
2288
- /**
2289
- * Return the deep keys list for all documents in the provided list
2290
- * @param list
2291
- * @param options
2292
- * @returns Array[Array[String]]
2293
- */
2294
- declare function deepKeysFromList(list: object[], options?: DeeksOptions): string[][];
2295
-
2296
- /**
2297
- Get the value of the property at the given path.
2298
-
2299
- @param object - Object or array to get the `path` value.
2300
- @param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
2301
- @param defaultValue - Default value.
2302
-
2303
- @example
2304
- ```
2305
- import {getProperty} from 'dot-prop';
2306
-
2307
- getProperty({foo: {bar: 'unicorn'}}, 'foo.bar');
2308
- //=> 'unicorn'
2309
-
2310
- getProperty({foo: {bar: 'a'}}, 'foo.notDefined.deep');
2311
- //=> undefined
2312
-
2313
- getProperty({foo: {bar: 'a'}}, 'foo.notDefined.deep', 'default value');
2314
- //=> 'default value'
2315
-
2316
- getProperty({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot');
2317
- //=> 'unicorn'
2318
-
2319
- getProperty({foo: [{bar: 'unicorn'}]}, 'foo[0].bar');
2320
- //=> 'unicorn'
2321
- ```
2322
- */
2323
- declare function getProperty<ObjectType, PathType extends string, DefaultValue = undefined>(
2324
- object: ObjectType,
2325
- path: PathType,
2326
- defaultValue?: DefaultValue
2327
- ): ObjectType extends Record<string, unknown> | unknown[] ? (unknown extends Get<ObjectType, PathType> ? DefaultValue : Get<ObjectType, PathType>) : undefined;
2328
-
2329
- /**
2330
- Set the property at the given path to the given value.
2331
-
2332
- @param object - Object or array to set the `path` value.
2333
- @param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
2334
- @param value - Value to set at `path`.
2335
- @returns The object.
2336
-
2337
- @example
2338
- ```
2339
- import {setProperty} from 'dot-prop';
2340
-
2341
- const object = {foo: {bar: 'a'}};
2342
- setProperty(object, 'foo.bar', 'b');
2343
- console.log(object);
2344
- //=> {foo: {bar: 'b'}}
2345
-
2346
- const foo = setProperty({}, 'foo.bar', 'c');
2347
- console.log(foo);
2348
- //=> {foo: {bar: 'c'}}
2349
-
2350
- setProperty(object, 'foo.baz', 'x');
2351
- console.log(object);
2352
- //=> {foo: {bar: 'b', baz: 'x'}}
2353
-
2354
- setProperty(object, 'foo.biz[0]', 'a');
2355
- console.log(object);
2356
- //=> {foo: {bar: 'b', baz: 'x', biz: ['a']}}
2357
- ```
2358
- */
2359
- declare function setProperty<ObjectType extends Record<string, any>>(
2360
- object: ObjectType,
2361
- path: string,
2362
- value: unknown
2363
- ): ObjectType;
2364
-
2365
- /**
2366
- Check whether the property at the given path exists.
2367
-
2368
- @param object - Object or array to test the `path` value.
2369
- @param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
2370
-
2371
- @example
2372
- ```
2373
- import {hasProperty} from 'dot-prop';
2374
-
2375
- hasProperty({foo: {bar: 'unicorn'}}, 'foo.bar');
2376
- //=> true
2377
- ```
2378
- */
2379
- declare function hasProperty(object: Record<string, any> | undefined, path: string): boolean;
2380
-
2381
- /**
2382
- Delete the property at the given path.
2383
-
2384
- @param object - Object or array to delete the `path` value.
2385
- @param path - Path of the property in the object, using `.` to separate each nested key. Use `\\.` if you have a `.` in the key.
2386
- @returns A boolean of whether the property existed before being deleted.
2387
-
2388
- @example
2389
- ```
2390
- import {deleteProperty} from 'dot-prop';
2391
-
2392
- const object = {foo: {bar: 'a'}};
2393
- deleteProperty(object, 'foo.bar');
2394
- console.log(object);
2395
- //=> {foo: {}}
2396
-
2397
- object.foo.bar = {x: 'y', y: 'x'};
2398
- deleteProperty(object, 'foo.bar.x');
2399
- console.log(object);
2400
- //=> {foo: {bar: {y: 'x'}}}
2401
- ```
2402
- */
2403
- declare function deleteProperty(object: Record<string, any>, path: string): boolean;
2404
-
2405
- /**
2406
- Escape special characters in a path. Useful for sanitizing user input.
2407
-
2408
- @param path - The dot path to sanitize.
2409
-
2410
- @example
2411
- ```
2412
- import {getProperty, escapePath} from 'dot-prop';
2413
-
2414
- const object = {
2415
- foo: {
2416
- bar: '👸🏻 You found me Mario!',
2417
- },
2418
- 'foo.bar' : '🍄 The princess is in another castle!',
2419
- };
2420
- const escapedPath = escapePath('foo.bar');
2421
-
2422
- console.log(getProperty(object, escapedPath));
2423
- //=> '🍄 The princess is in another castle!'
2424
- ```
2425
- */
2426
- declare function escapePath(path: string): string;
2427
-
2428
- /**
2429
- Check if a value is a plain object.
2430
-
2431
- An object is plain if it's created by either `{}`, `new Object()`, or `Object.create(null)`.
2432
-
2433
- @example
2434
- ```
2435
- import isPlainObject from 'is-plain-obj';
2436
- import {runInNewContext} from 'node:vm';
2437
-
2438
- isPlainObject({foo: 'bar'});
2439
- //=> true
2440
-
2441
- isPlainObject(new Object());
2442
- //=> true
2443
-
2444
- isPlainObject(Object.create(null));
2445
- //=> true
2446
-
2447
- // This works across realms
2448
- isPlainObject(runInNewContext('({})'));
2449
- //=> true
2450
-
2451
- isPlainObject([1, 2, 3]);
2452
- //=> false
2453
-
2454
- class Unicorn {}
2455
- isPlainObject(new Unicorn());
2456
- //=> false
2457
-
2458
- isPlainObject(Math);
2459
- //=> false
2460
- ```
2461
- */
2462
- declare function isPlainObject<Value>(value: unknown): value is Record<PropertyKey, Value>;
2463
-
2464
- export { type DeeksOptions as DeepKeysOptions, type OmitDeep, type Paths, type PickDeep, type Split, deepKeys, deepKeysFromList, deleteProperty, escapePath, getProperty, hasProperty, isPlainObject, omit, pick, setProperty };
1
+ export { default as omit } from "./omit.d.cts";
2
+ export { default as pick } from "./pick.d.cts";
3
+ export type { DeeksOptions as DeepKeysOptions } from "deeks";
4
+ export { deepKeys, deepKeysFromList } from "deeks";
5
+ export { deleteProperty, escapePath, getProperty, hasProperty, setProperty } from "dot-prop";
6
+ export { default as isPlainObject } from "is-plain-obj";
7
+ export type { OmitDeep, Paths, PickDeep, Split } from "type-fest";