@visulima/object 1.0.0 → 1.0.1

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
@@ -166,6 +166,71 @@ fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface`
166
166
  */
167
167
  type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
168
168
 
169
+ /**
170
+ Returns the static, fixed-length portion of the given array, excluding variable-length parts.
171
+
172
+ @example
173
+ ```
174
+ type A = [string, number, boolean, ...string[]];
175
+ type B = StaticPartOfArray<A>;
176
+ //=> [string, number, boolean]
177
+ ```
178
+ */
179
+ type StaticPartOfArray<T extends UnknownArray, Result extends UnknownArray = []> =
180
+ T extends unknown
181
+ ? number extends T['length'] ?
182
+ T extends readonly [infer U, ...infer V]
183
+ ? StaticPartOfArray<V, [...Result, U]>
184
+ : Result
185
+ : T
186
+ : never; // Should never happen
187
+
188
+ /**
189
+ Returns the variable, non-fixed-length portion of the given array, excluding static-length parts.
190
+
191
+ @example
192
+ ```
193
+ type A = [string, number, boolean, ...string[]];
194
+ type B = VariablePartOfArray<A>;
195
+ //=> string[]
196
+ ```
197
+ */
198
+ type VariablePartOfArray<T extends UnknownArray> =
199
+ T extends unknown
200
+ ? T extends readonly [...StaticPartOfArray<T>, ...infer U]
201
+ ? U
202
+ : []
203
+ : never; // Should never happen
204
+
205
+ /**
206
+ Set the given array to readonly if `IsReadonly` is `true`, otherwise set the given array to normal, then return the result.
207
+
208
+ @example
209
+ ```
210
+ type ReadonlyArray = readonly string[];
211
+ type NormalArray = string[];
212
+
213
+ type ReadonlyResult = SetArrayAccess<NormalArray, true>;
214
+ //=> readonly string[]
215
+
216
+ type NormalResult = SetArrayAccess<ReadonlyArray, false>;
217
+ //=> string[]
218
+ ```
219
+ */
220
+ type SetArrayAccess<T extends UnknownArray, IsReadonly extends boolean> =
221
+ T extends readonly [...infer U] ?
222
+ IsReadonly extends true
223
+ ? readonly [...U]
224
+ : [...U]
225
+ : T;
226
+
227
+ /**
228
+ Returns whether the given array `T` is readonly.
229
+ */
230
+ type IsArrayReadonly<T extends UnknownArray> = T extends unknown[] ? false : true;
231
+
232
+ type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
233
+
169
234
  /**
170
235
  Returns a boolean for whether the given type is `any`.
171
236
 
@@ -255,6 +320,49 @@ type ShouldBeTrue = IsNegative<-1>;
255
320
  */
256
321
  type IsNegative<T extends Numeric> = T extends Negative<T> ? true : false;
257
322
 
323
+ /**
324
+ Returns a boolean for whether the given type is `never`.
325
+
326
+ @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
327
+ @link https://stackoverflow.com/a/53984913/10292952
328
+ @link https://www.zhenghao.io/posts/ts-never
329
+
330
+ Useful in type utilities, such as checking if something does not occur.
331
+
332
+ @example
333
+ ```
334
+ import type {IsNever, And} from 'type-fest';
335
+
336
+ // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
337
+ type AreStringsEqual<A extends string, B extends string> =
338
+ And<
339
+ IsNever<Exclude<A, B>> extends true ? true : false,
340
+ IsNever<Exclude<B, A>> extends true ? true : false
341
+ >;
342
+
343
+ type EndIfEqual<I extends string, O extends string> =
344
+ AreStringsEqual<I, O> extends true
345
+ ? never
346
+ : void;
347
+
348
+ function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
349
+ if (input === output) {
350
+ process.exit(0);
351
+ }
352
+ }
353
+
354
+ endIfEqual('abc', 'abc');
355
+ //=> never
356
+
357
+ endIfEqual('abc', '123');
358
+ //=> void
359
+ ```
360
+
361
+ @category Type Guard
362
+ @category Utilities
363
+ */
364
+ type IsNever<T> = [T] extends [never] ? true : false;
365
+
258
366
  /**
259
367
  Returns a boolean for whether two given types are both true.
260
368
 
@@ -391,49 +499,6 @@ type LessThan<A extends number, B extends number> = number extends A | B
391
499
  ? never
392
500
  : GreaterThanOrEqual<A, B> extends true ? false : true;
393
501
 
394
- /**
395
- Returns a boolean for whether the given type is `never`.
396
-
397
- @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
398
- @link https://stackoverflow.com/a/53984913/10292952
399
- @link https://www.zhenghao.io/posts/ts-never
400
-
401
- Useful in type utilities, such as checking if something does not occur.
402
-
403
- @example
404
- ```
405
- import type {IsNever, And} from 'type-fest';
406
-
407
- // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
408
- type AreStringsEqual<A extends string, B extends string> =
409
- And<
410
- IsNever<Exclude<A, B>> extends true ? true : false,
411
- IsNever<Exclude<B, A>> extends true ? true : false
412
- >;
413
-
414
- type EndIfEqual<I extends string, O extends string> =
415
- AreStringsEqual<I, O> extends true
416
- ? never
417
- : void;
418
-
419
- function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
420
- if (input === output) {
421
- process.exit(0);
422
- }
423
- }
424
-
425
- endIfEqual('abc', 'abc');
426
- //=> never
427
-
428
- endIfEqual('abc', '123');
429
- //=> void
430
- ```
431
-
432
- @category Type Guard
433
- @category Utilities
434
- */
435
- type IsNever<T> = [T] extends [never] ? true : false;
436
-
437
502
  /**
438
503
  Infer the length of the given tuple `<T>`.
439
504
 
@@ -473,45 +538,57 @@ type BuildTuple<L extends number, Fill = unknown, T extends readonly unknown[] =
473
538
  : BuildTuple<L, Fill, [...T, Fill]>;
474
539
 
475
540
  /**
476
- Create an object type with the given key `<Key>` and value `<Value>`.
541
+ Returns the maximum value from a tuple of integers.
477
542
 
478
- It will copy the prefix and optional status of the same key from the given object `CopiedFrom` into the result.
543
+ Note:
544
+ - Float numbers are not supported.
479
545
 
480
546
  @example
481
547
  ```
482
- type A = BuildObject<'a', string>;
483
- //=> {a: string}
548
+ ArrayMax<[1, 2, 5, 3]>;
549
+ //=> 5
484
550
 
485
- // Copy `readonly` and `?` from the key `a` of `{readonly a?: any}`
486
- type B = BuildObject<'a', string, {readonly a?: any}>;
487
- //=> {readonly a?: string}
551
+ ArrayMax<[1, 2, 5, 3, 99, -1]>;
552
+ //=> 99
488
553
  ```
489
554
  */
490
- type BuildObject<Key extends PropertyKey, Value, CopiedFrom extends object = {}> =
491
- Key extends keyof CopiedFrom
492
- ? Pick<{[_ in keyof CopiedFrom]: Value}, Key>
493
- : Key extends `${infer NumberKey extends number}`
494
- ? NumberKey extends keyof CopiedFrom
495
- ? Pick<{[_ in keyof CopiedFrom]: Value}, NumberKey>
496
- : {[_ in Key]: Value}
497
- : {[_ in Key]: Value};
555
+ type TupleMax<A extends number[], Result extends number = NegativeInfinity> = number extends A[number]
556
+ ? never :
557
+ A extends [infer F extends number, ...infer R extends number[]]
558
+ ? GreaterThan<F, Result> extends true
559
+ ? TupleMax<R, F>
560
+ : TupleMax<R, Result>
561
+ : Result;
498
562
 
499
563
  /**
500
- Return a string representation of the given string or number.
564
+ Returns the minimum value from a tuple of integers.
501
565
 
502
- Note: This type is not the return type of the `.toString()` function.
503
- */
504
- type ToString<T> = T extends string | number ? `${T}` : never;
566
+ Note:
567
+ - Float numbers are not supported.
505
568
 
506
- /**
507
- Matches any primitive, `void`, `Date`, or `RegExp` value.
569
+ @example
570
+ ```
571
+ ArrayMin<[1, 2, 5, 3]>;
572
+ //=> 1
573
+
574
+ ArrayMin<[1, 2, 5, 3, -5]>;
575
+ //=> -5
576
+ ```
508
577
  */
509
- type BuiltIns = Primitive | void | Date | RegExp;
578
+ type TupleMin<A extends number[], Result extends number = PositiveInfinity> = number extends A[number]
579
+ ? never
580
+ : A extends [infer F extends number, ...infer R extends number[]]
581
+ ? LessThan<F, Result> extends true
582
+ ? TupleMin<R, F>
583
+ : TupleMin<R, Result>
584
+ : Result;
510
585
 
511
586
  /**
512
- Matches non-recursive types.
587
+ Return a string representation of the given string or number.
588
+
589
+ Note: This type is not the return type of the `.toString()` function.
513
590
  */
514
- type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
591
+ type ToString<T> = T extends string | number ? `${T}` : never;
515
592
 
516
593
  /**
517
594
  Converts a numeric string to a number.
@@ -549,6 +626,26 @@ type StringToNumber<S extends string> = S extends `${infer N extends number}`
549
626
  ? NegativeInfinity
550
627
  : never;
551
628
 
629
+ /**
630
+ Returns an array of the characters of the string.
631
+
632
+ @example
633
+ ```
634
+ StringToArray<'abcde'>;
635
+ //=> ['a', 'b', 'c', 'd', 'e']
636
+
637
+ StringToArray<string>;
638
+ //=> never
639
+ ```
640
+
641
+ @category String
642
+ */
643
+ type StringToArray<S extends string, Result extends string[] = []> = string extends S
644
+ ? never
645
+ : S extends `${infer F}${infer R}`
646
+ ? StringToArray<R, [...Result, F]>
647
+ : Result;
648
+
552
649
  /**
553
650
  Returns the length of the given string.
554
651
 
@@ -569,130 +666,29 @@ type StringLength<S extends string> = string extends S
569
666
  : StringToArray<S>['length'];
570
667
 
571
668
  /**
572
- Returns an array of the characters of the string.
669
+ 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.
573
670
 
574
671
  @example
575
672
  ```
576
- StringToArray<'abcde'>;
577
- //=> ['a', 'b', 'c', 'd', 'e']
673
+ SameLengthPositiveNumericStringGt<'50', '10'>;
674
+ //=> true
578
675
 
579
- StringToArray<string>;
580
- //=> never
676
+ SameLengthPositiveNumericStringGt<'10', '10'>;
677
+ //=> false
581
678
  ```
582
-
583
- @category String
584
679
  */
585
- type StringToArray<S extends string, Result extends string[] = []> = string extends S
586
- ? never
587
- : S extends `${infer F}${infer R}`
588
- ? StringToArray<R, [...Result, F]>
589
- : Result;
680
+ type SameLengthPositiveNumericStringGt<A extends string, B extends string> = A extends `${infer FirstA}${infer RestA}`
681
+ ? B extends `${infer FirstB}${infer RestB}`
682
+ ? FirstA extends FirstB
683
+ ? SameLengthPositiveNumericStringGt<RestA, RestB>
684
+ : PositiveNumericCharacterGt<FirstA, FirstB>
685
+ : never
686
+ : false;
590
687
 
591
- type StringDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
688
+ type NumericString = '0123456789';
592
689
 
593
690
  /**
594
- Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
595
-
596
- It creates a type-safe way to access the member type of `unknown` type.
597
- */
598
- type ObjectValue<T, K> =
599
- K extends keyof T
600
- ? T[K]
601
- : ToString<K> extends keyof T
602
- ? T[ToString<K>]
603
- : K extends `${infer NumberK extends number}`
604
- ? NumberK extends keyof T
605
- ? T[NumberK]
606
- : never
607
- : never;
608
-
609
- /**
610
- Returns the maximum value from a tuple of integers.
611
-
612
- Note:
613
- - Float numbers are not supported.
614
-
615
- @example
616
- ```
617
- ArrayMax<[1, 2, 5, 3]>;
618
- //=> 5
619
-
620
- ArrayMax<[1, 2, 5, 3, 99, -1]>;
621
- //=> 99
622
- ```
623
- */
624
- type ArrayMax<A extends number[], Result extends number = NegativeInfinity> = number extends A[number]
625
- ? never :
626
- A extends [infer F extends number, ...infer R extends number[]]
627
- ? GreaterThan<F, Result> extends true
628
- ? ArrayMax<R, F>
629
- : ArrayMax<R, Result>
630
- : Result;
631
-
632
- /**
633
- Returns the minimum value from a tuple of integers.
634
-
635
- Note:
636
- - Float numbers are not supported.
637
-
638
- @example
639
- ```
640
- ArrayMin<[1, 2, 5, 3]>;
641
- //=> 1
642
-
643
- ArrayMin<[1, 2, 5, 3, -5]>;
644
- //=> -5
645
- ```
646
- */
647
- type ArrayMin<A extends number[], Result extends number = PositiveInfinity> = number extends A[number]
648
- ? never
649
- : A extends [infer F extends number, ...infer R extends number[]]
650
- ? LessThan<F, Result> extends true
651
- ? ArrayMin<R, F>
652
- : ArrayMin<R, Result>
653
- : Result;
654
-
655
- /**
656
- Returns the absolute value of a given value.
657
-
658
- @example
659
- ```
660
- NumberAbsolute<-1>;
661
- //=> 1
662
-
663
- NumberAbsolute<1>;
664
- //=> 1
665
-
666
- NumberAbsolute<NegativeInfinity>
667
- //=> PositiveInfinity
668
- ```
669
- */
670
- type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
671
-
672
- /**
673
- 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.
674
-
675
- @example
676
- ```
677
- SameLengthPositiveNumericStringGt<'50', '10'>;
678
- //=> true
679
-
680
- SameLengthPositiveNumericStringGt<'10', '10'>;
681
- //=> false
682
- ```
683
- */
684
- type SameLengthPositiveNumericStringGt<A extends string, B extends string> = A extends `${infer FirstA}${infer RestA}`
685
- ? B extends `${infer FirstB}${infer RestB}`
686
- ? FirstA extends FirstB
687
- ? SameLengthPositiveNumericStringGt<RestA, RestB>
688
- : PositiveNumericCharacterGt<FirstA, FirstB>
689
- : never
690
- : false;
691
-
692
- type NumericString = '0123456789';
693
-
694
- /**
695
- Returns a boolean for whether `A` is greater than `B`, where `A` and `B` are both positive numeric strings.
691
+ Returns a boolean for whether `A` is greater than `B`, where `A` and `B` are both positive numeric strings.
696
692
 
697
693
  @example
698
694
  ```
@@ -737,40 +733,57 @@ type PositiveNumericCharacterGt<A extends string, B extends string> = NumericStr
737
733
  : never;
738
734
 
739
735
  /**
740
- Returns the static, fixed-length portion of the given array, excluding variable-length parts.
736
+ Get the exact version of the given `Key` in the given object `T`.
737
+
738
+ 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.
741
739
 
742
740
  @example
743
741
  ```
744
- type A = [string, number, boolean, ...string[]];
745
- type B = StaticPartOfArray<A>;
746
- //=> [string, number, boolean]
742
+ type Object = {
743
+ 0: number;
744
+ '1': string;
745
+ };
746
+
747
+ type Key1 = ExactKey<Object, '0'>;
748
+ //=> 0
749
+ type Key2 = ExactKey<Object, 0>;
750
+ //=> 0
751
+
752
+ type Key3 = ExactKey<Object, '1'>;
753
+ //=> '1'
754
+ type Key4 = ExactKey<Object, 1>;
755
+ //=> '1'
747
756
  ```
757
+
758
+ @category Object
748
759
  */
749
- type StaticPartOfArray<T extends UnknownArray, Result extends UnknownArray = []> =
750
- T extends unknown
751
- ? number extends T['length'] ?
752
- T extends readonly [infer U, ...infer V]
753
- ? StaticPartOfArray<V, [...Result, U]>
754
- : Result
755
- : T
756
- : never; // Should never happen
760
+ type ExactKey<T extends object, Key extends PropertyKey> =
761
+ Key extends keyof T
762
+ ? Key
763
+ : ToString<Key> extends keyof T
764
+ ? ToString<Key>
765
+ : Key extends `${infer NumberKey extends number}`
766
+ ? NumberKey extends keyof T
767
+ ? NumberKey
768
+ : never
769
+ : never;
757
770
 
758
771
  /**
759
- Returns the variable, non-fixed-length portion of the given array, excluding static-length parts.
772
+ Returns the absolute value of a given value.
760
773
 
761
774
  @example
762
775
  ```
763
- type A = [string, number, boolean, ...string[]];
764
- type B = VariablePartOfArray<A>;
765
- //=> string[]
776
+ NumberAbsolute<-1>;
777
+ //=> 1
778
+
779
+ NumberAbsolute<1>;
780
+ //=> 1
781
+
782
+ NumberAbsolute<NegativeInfinity>
783
+ //=> PositiveInfinity
766
784
  ```
767
785
  */
768
- type VariablePartOfArray<T extends UnknownArray> =
769
- T extends unknown
770
- ? T extends readonly [...StaticPartOfArray<T>, ...infer U]
771
- ? U
772
- : []
773
- : never; // Should never happen
786
+ type NumberAbsolute<N extends number> = `${N}` extends `-${infer StringPositiveN}` ? StringToNumber<StringPositiveN> : N;
774
787
 
775
788
  /**
776
789
  Returns the minimum number in the given union of numbers.
@@ -816,6 +829,16 @@ type InternalUnionMax<N extends number, T extends UnknownArray = []> =
816
829
  ? InternalUnionMax<Exclude<N, T['length']>, T>
817
830
  : InternalUnionMax<N, [...T, unknown]>;
818
831
 
832
+ /**
833
+ Matches any primitive, `void`, `Date`, or `RegExp` value.
834
+ */
835
+ type BuiltIns = Primitive | void | Date | RegExp;
836
+
837
+ /**
838
+ Matches non-recursive types.
839
+ */
840
+ type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
841
+
819
842
  /**
820
843
  Returns a boolean for whether the given type is a union type.
821
844
 
@@ -852,67 +875,44 @@ type InternalIsUnion<T, U = T> =
852
875
  : never; // Should never happen
853
876
 
854
877
  /**
855
- Set the given array to readonly if `IsReadonly` is `true`, otherwise set the given array to normal, then return the result.
878
+ Create an object type with the given key `<Key>` and value `<Value>`.
879
+
880
+ It will copy the prefix and optional status of the same key from the given object `CopiedFrom` into the result.
856
881
 
857
882
  @example
858
883
  ```
859
- type ReadonlyArray = readonly string[];
860
- type NormalArray = string[];
861
-
862
- type ReadonlyResult = SetArrayAccess<NormalArray, true>;
863
- //=> readonly string[]
884
+ type A = BuildObject<'a', string>;
885
+ //=> {a: string}
864
886
 
865
- type NormalResult = SetArrayAccess<ReadonlyArray, false>;
866
- //=> string[]
887
+ // Copy `readonly` and `?` from the key `a` of `{readonly a?: any}`
888
+ type B = BuildObject<'a', string, {readonly a?: any}>;
889
+ //=> {readonly a?: string}
867
890
  ```
868
891
  */
869
- type SetArrayAccess<T extends UnknownArray, IsReadonly extends boolean> =
870
- T extends readonly [...infer U] ?
871
- IsReadonly extends true
872
- ? readonly [...U]
873
- : [...U]
874
- : T;
875
-
876
- /**
877
- Returns whether the given array `T` is readonly.
878
- */
879
- type IsArrayReadonly<T extends UnknownArray> = T extends unknown[] ? false : true;
892
+ type BuildObject<Key extends PropertyKey, Value, CopiedFrom extends object = {}> =
893
+ Key extends keyof CopiedFrom
894
+ ? Pick<{[_ in keyof CopiedFrom]: Value}, Key>
895
+ : Key extends `${infer NumberKey extends number}`
896
+ ? NumberKey extends keyof CopiedFrom
897
+ ? Pick<{[_ in keyof CopiedFrom]: Value}, NumberKey>
898
+ : {[_ in Key]: Value}
899
+ : {[_ in Key]: Value};
880
900
 
881
901
  /**
882
- Get the exact version of the given `Key` in the given object `T`.
883
-
884
- 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.
885
-
886
- @example
887
- ```
888
- type Object = {
889
- 0: number;
890
- '1': string;
891
- };
892
-
893
- type Key1 = ExactKey<Object, '0'>;
894
- //=> 0
895
- type Key2 = ExactKey<Object, 0>;
896
- //=> 0
897
-
898
- type Key3 = ExactKey<Object, '1'>;
899
- //=> '1'
900
- type Key4 = ExactKey<Object, 1>;
901
- //=> '1'
902
- ```
902
+ Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
903
903
 
904
- @category Object
904
+ It creates a type-safe way to access the member type of `unknown` type.
905
905
  */
906
- type ExactKey<T extends object, Key extends PropertyKey> =
907
- Key extends keyof T
908
- ? Key
909
- : ToString<Key> extends keyof T
910
- ? ToString<Key>
911
- : Key extends `${infer NumberKey extends number}`
912
- ? NumberKey extends keyof T
913
- ? NumberKey
914
- : never
915
- : never;
906
+ type ObjectValue<T, K> =
907
+ K extends keyof T
908
+ ? T[K]
909
+ : ToString<K> extends keyof T
910
+ ? T[ToString<K>]
911
+ : K extends `${infer NumberK extends number}`
912
+ ? NumberK extends keyof T
913
+ ? T[NumberK]
914
+ : never
915
+ : never;
916
916
 
917
917
  /**
918
918
  Deeply simplifies an object type.
@@ -1028,132 +1028,146 @@ type SimplifyDeep<Type, ExcludeType = never> =
1028
1028
  >;
1029
1029
 
1030
1030
  /**
1031
- Returns the difference between two numbers.
1031
+ Returns the sum of two numbers.
1032
1032
 
1033
1033
  Note:
1034
1034
  - A or B can only support `-999` ~ `999`.
1035
+ - A and B can only be small integers, less than 1000.
1035
1036
  - If the result is negative, you can only get `number`.
1036
1037
 
1037
1038
  @example
1038
1039
  ```
1039
- import type {Subtract} from 'type-fest';
1040
-
1041
- Subtract<333, 222>;
1042
- //=> 111
1040
+ import type {Sum} from 'type-fest';
1043
1041
 
1044
- Subtract<111, -222>;
1042
+ Sum<111, 222>;
1045
1043
  //=> 333
1046
1044
 
1047
- Subtract<-111, 222>;
1045
+ Sum<-111, 222>;
1046
+ //=> 111
1047
+
1048
+ Sum<111, -222>;
1048
1049
  //=> number
1049
1050
 
1050
- Subtract<PositiveInfinity, 9999>;
1051
+ Sum<PositiveInfinity, -9999>;
1051
1052
  //=> PositiveInfinity
1052
1053
 
1053
- Subtract<PositiveInfinity, PositiveInfinity>;
1054
+ Sum<PositiveInfinity, NegativeInfinity>;
1054
1055
  //=> number
1055
1056
  ```
1056
1057
 
1057
1058
  @category Numeric
1058
1059
  */
1059
1060
  // TODO: Support big integer and negative number.
1060
- type Subtract<A extends number, B extends number> = number extends A | B
1061
+ type Sum<A extends number, B extends number> = number extends A | B
1061
1062
  ? number
1062
1063
  : [
1063
1064
  IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
1064
1065
  IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
1065
1066
  ] extends infer R extends [boolean, boolean, boolean, boolean]
1066
1067
  ? Or<
1067
- And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
1068
- And<IsEqual<R[3], true>, IsEqual<R[1], false>>
1068
+ And<IsEqual<R[0], true>, IsEqual<R[3], false>>,
1069
+ And<IsEqual<R[2], true>, IsEqual<R[1], false>>
1069
1070
  > extends true
1070
1071
  ? PositiveInfinity
1071
1072
  : Or<
1072
- And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
1073
- And<IsEqual<R[2], true>, IsEqual<R[0], false>>
1073
+ And<IsEqual<R[1], true>, IsEqual<R[2], false>>,
1074
+ And<IsEqual<R[3], true>, IsEqual<R[0], false>>
1074
1075
  > extends true
1075
1076
  ? NegativeInfinity
1076
1077
  : true extends R[number]
1077
1078
  ? number
1078
- : [IsNegative<A>, IsNegative<B>] extends infer R
1079
+ : ([IsNegative<A>, IsNegative<B>] extends infer R
1079
1080
  ? [false, false] extends R
1080
- ? BuildTuple<A> extends infer R
1081
- ? R extends [...BuildTuple<B>, ...infer R]
1082
- ? R['length']
1083
- : number
1084
- : never
1085
- : LessThan<A, B> extends true
1081
+ ? [...BuildTuple<A>, ...BuildTuple<B>]['length']
1082
+ : [true, true] extends R
1086
1083
  ? number
1087
- : [false, true] extends R
1088
- ? Sum<A, NumberAbsolute<B>>
1089
- : Subtract<NumberAbsolute<B>, NumberAbsolute<A>>
1090
- : never
1084
+ : TupleMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_
1085
+ ? TupleMin<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Min_ extends number
1086
+ ? Max_ extends A | B
1087
+ ? Subtract<Max_, Min_>
1088
+ : number
1089
+ : never
1090
+ : never
1091
+ : never) & number
1091
1092
  : never;
1092
1093
 
1093
1094
  /**
1094
- Returns the sum of two numbers.
1095
+ Returns the difference between two numbers.
1095
1096
 
1096
1097
  Note:
1097
1098
  - A or B can only support `-999` ~ `999`.
1098
- - A and B can only be small integers, less than 1000.
1099
1099
  - If the result is negative, you can only get `number`.
1100
1100
 
1101
1101
  @example
1102
1102
  ```
1103
- import type {Sum} from 'type-fest';
1104
-
1105
- Sum<111, 222>;
1106
- //=> 333
1103
+ import type {Subtract} from 'type-fest';
1107
1104
 
1108
- Sum<-111, 222>;
1105
+ Subtract<333, 222>;
1109
1106
  //=> 111
1110
1107
 
1111
- Sum<111, -222>;
1108
+ Subtract<111, -222>;
1109
+ //=> 333
1110
+
1111
+ Subtract<-111, 222>;
1112
1112
  //=> number
1113
1113
 
1114
- Sum<PositiveInfinity, -9999>;
1114
+ Subtract<PositiveInfinity, 9999>;
1115
1115
  //=> PositiveInfinity
1116
1116
 
1117
- Sum<PositiveInfinity, NegativeInfinity>;
1117
+ Subtract<PositiveInfinity, PositiveInfinity>;
1118
1118
  //=> number
1119
1119
  ```
1120
1120
 
1121
1121
  @category Numeric
1122
1122
  */
1123
1123
  // TODO: Support big integer and negative number.
1124
- type Sum<A extends number, B extends number> = number extends A | B
1124
+ type Subtract<A extends number, B extends number> = number extends A | B
1125
1125
  ? number
1126
1126
  : [
1127
1127
  IsEqual<A, PositiveInfinity>, IsEqual<A, NegativeInfinity>,
1128
1128
  IsEqual<B, PositiveInfinity>, IsEqual<B, NegativeInfinity>,
1129
1129
  ] extends infer R extends [boolean, boolean, boolean, boolean]
1130
1130
  ? Or<
1131
- And<IsEqual<R[0], true>, IsEqual<R[3], false>>,
1132
- And<IsEqual<R[2], true>, IsEqual<R[1], false>>
1131
+ And<IsEqual<R[0], true>, IsEqual<R[2], false>>,
1132
+ And<IsEqual<R[3], true>, IsEqual<R[1], false>>
1133
1133
  > extends true
1134
1134
  ? PositiveInfinity
1135
1135
  : Or<
1136
- And<IsEqual<R[1], true>, IsEqual<R[2], false>>,
1137
- And<IsEqual<R[3], true>, IsEqual<R[0], false>>
1136
+ And<IsEqual<R[1], true>, IsEqual<R[3], false>>,
1137
+ And<IsEqual<R[2], true>, IsEqual<R[0], false>>
1138
1138
  > extends true
1139
1139
  ? NegativeInfinity
1140
1140
  : true extends R[number]
1141
1141
  ? number
1142
- : ([IsNegative<A>, IsNegative<B>] extends infer R
1142
+ : [IsNegative<A>, IsNegative<B>] extends infer R
1143
1143
  ? [false, false] extends R
1144
- ? [...BuildTuple<A>, ...BuildTuple<B>]['length']
1145
- : [true, true] extends R
1144
+ ? BuildTuple<A> extends infer R
1145
+ ? R extends [...BuildTuple<B>, ...infer R]
1146
+ ? R['length']
1147
+ : number
1148
+ : never
1149
+ : LessThan<A, B> extends true
1146
1150
  ? number
1147
- : ArrayMax<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Max_
1148
- ? ArrayMin<[NumberAbsolute<A>, NumberAbsolute<B>]> extends infer Min_ extends number
1149
- ? Max_ extends A | B
1150
- ? Subtract<Max_, Min_>
1151
- : number
1152
- : never
1153
- : never
1154
- : never) & number
1151
+ : [false, true] extends R
1152
+ ? Sum<A, NumberAbsolute<B>>
1153
+ : Subtract<NumberAbsolute<B>, NumberAbsolute<A>>
1154
+ : never
1155
1155
  : never;
1156
1156
 
1157
+ /**
1158
+ Paths options.
1159
+
1160
+ @see {@link Paths}
1161
+ */
1162
+ type PathsOptions = {
1163
+ /**
1164
+ The maximum depth to recurse when searching for paths.
1165
+
1166
+ @default 10
1167
+ */
1168
+ maxRecursionDepth?: number;
1169
+ };
1170
+
1157
1171
  /**
1158
1172
  Generate a union of all possible paths to properties in the given object.
1159
1173
 
@@ -1195,9 +1209,7 @@ open('listB.1'); // TypeError. Because listB only has one element.
1195
1209
  @category Object
1196
1210
  @category Array
1197
1211
  */
1198
- type Paths<T> = Paths_<T>;
1199
-
1200
- type Paths_<T, Depth extends number = 0> =
1212
+ type Paths<T, Options extends PathsOptions = {}> =
1201
1213
  T extends NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
1202
1214
  ? never
1203
1215
  : IsAny<T> extends true
@@ -1205,32 +1217,36 @@ type Paths_<T, Depth extends number = 0> =
1205
1217
  : T extends UnknownArray
1206
1218
  ? number extends T['length']
1207
1219
  // We need to handle the fixed and non-fixed index part of the array separately.
1208
- ? InternalPaths<StaticPartOfArray<T>, Depth>
1209
- | InternalPaths<Array<VariablePartOfArray<T>[number]>, Depth>
1210
- : InternalPaths<T, Depth>
1220
+ ? InternalPaths<StaticPartOfArray<T>, Options>
1221
+ | InternalPaths<Array<VariablePartOfArray<T>[number]>, Options>
1222
+ : InternalPaths<T, Options>
1211
1223
  : T extends object
1212
- ? InternalPaths<T, Depth>
1224
+ ? InternalPaths<T, Options>
1213
1225
  : never;
1214
1226
 
1215
- type InternalPaths<_T, Depth extends number = 0, T = Required<_T>> =
1216
- T extends EmptyObject | readonly []
1217
- ? never
1218
- : {
1219
- [Key in keyof T]:
1220
- Key extends string | number // Limit `Key` to string or number.
1221
- // If `Key` is a number, return `Key | `${Key}``, because both `array[0]` and `array['0']` work.
1222
- ?
1223
- | Key
1224
- | ToString<Key>
1225
- | (
1226
- LessThan<Depth, 15> extends true // Limit the depth to prevent infinite recursion
1227
- ? IsNever<Paths_<T[Key], Sum<Depth, 1>>> extends false
1228
- ? `${Key}.${Paths_<T[Key], Sum<Depth, 1>>}`
1229
- : never
1227
+ type InternalPaths<T, Options extends PathsOptions = {}> =
1228
+ (Options['maxRecursionDepth'] extends number ? Options['maxRecursionDepth'] : 10) extends infer MaxDepth extends number
1229
+ ? Required<T> extends infer T
1230
+ ? T extends EmptyObject | readonly []
1231
+ ? never
1232
+ : {
1233
+ [Key in keyof T]:
1234
+ Key extends string | number // Limit `Key` to string or number.
1235
+ // If `Key` is a number, return `Key | `${Key}``, because both `array[0]` and `array['0']` work.
1236
+ ?
1237
+ | Key
1238
+ | ToString<Key>
1239
+ | (
1240
+ GreaterThan<MaxDepth, 0> extends true // Limit the depth to prevent infinite recursion
1241
+ ? IsNever<Paths<T[Key], {maxRecursionDepth: Subtract<MaxDepth, 1>}>> extends false
1242
+ ? `${Key}.${Paths<T[Key], {maxRecursionDepth: Subtract<MaxDepth, 1>}>}`
1243
+ : never
1244
+ : never
1245
+ )
1230
1246
  : never
1231
- )
1232
- : never
1233
- }[keyof T & (T extends UnknownArray ? number : unknown)];
1247
+ }[keyof T & (T extends UnknownArray ? number : unknown)]
1248
+ : never
1249
+ : never;
1234
1250
 
1235
1251
  /**
1236
1252
  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).