ts-data-forge 1.5.1 → 2.0.0

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.
Files changed (82) hide show
  1. package/README.md +13 -1
  2. package/dist/array/array-utils.d.mts +693 -351
  3. package/dist/array/array-utils.d.mts.map +1 -1
  4. package/dist/array/array-utils.mjs +474 -1541
  5. package/dist/array/array-utils.mjs.map +1 -1
  6. package/dist/array/index.d.mts +0 -1
  7. package/dist/array/index.d.mts.map +1 -1
  8. package/dist/array/index.mjs +0 -1
  9. package/dist/array/index.mjs.map +1 -1
  10. package/dist/collections/imap-mapped.mjs.map +1 -1
  11. package/dist/collections/imap.mjs.map +1 -1
  12. package/dist/collections/iset-mapped.mjs.map +1 -1
  13. package/dist/collections/iset.mjs.map +1 -1
  14. package/dist/collections/queue.mjs +0 -1
  15. package/dist/collections/queue.mjs.map +1 -1
  16. package/dist/collections/stack.mjs +4 -5
  17. package/dist/collections/stack.mjs.map +1 -1
  18. package/dist/functional/match.d.mts +2 -33
  19. package/dist/functional/match.d.mts.map +1 -1
  20. package/dist/functional/match.mjs +2 -119
  21. package/dist/functional/match.mjs.map +1 -1
  22. package/dist/functional/optional.d.mts +29 -51
  23. package/dist/functional/optional.d.mts.map +1 -1
  24. package/dist/functional/optional.mjs +40 -171
  25. package/dist/functional/optional.mjs.map +1 -1
  26. package/dist/functional/pipe.d.mts +2 -15
  27. package/dist/functional/pipe.d.mts.map +1 -1
  28. package/dist/functional/pipe.mjs +2 -110
  29. package/dist/functional/pipe.mjs.map +1 -1
  30. package/dist/functional/result.d.mts +18 -45
  31. package/dist/functional/result.d.mts.map +1 -1
  32. package/dist/functional/result.mjs +40 -196
  33. package/dist/functional/result.mjs.map +1 -1
  34. package/dist/globals.d.mts +10 -9
  35. package/dist/index.mjs +0 -1
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/iterator/range.d.mts +2 -6
  38. package/dist/iterator/range.d.mts.map +1 -1
  39. package/dist/iterator/range.mjs +2 -93
  40. package/dist/iterator/range.mjs.map +1 -1
  41. package/dist/json/json.mjs +0 -1
  42. package/dist/json/json.mjs.map +1 -1
  43. package/dist/number/num.d.mts +3 -6
  44. package/dist/number/num.d.mts.map +1 -1
  45. package/dist/number/num.mjs +4 -22
  46. package/dist/number/num.mjs.map +1 -1
  47. package/dist/number/refined-number-utils.mjs.map +1 -1
  48. package/dist/object/object.d.mts +4 -10
  49. package/dist/object/object.d.mts.map +1 -1
  50. package/dist/object/object.mjs +8 -140
  51. package/dist/object/object.mjs.map +1 -1
  52. package/dist/others/map-nullable.d.mts +2 -6
  53. package/dist/others/map-nullable.d.mts.map +1 -1
  54. package/dist/others/map-nullable.mjs +2 -146
  55. package/dist/others/map-nullable.mjs.map +1 -1
  56. package/dist/others/memoize-function.mjs.map +1 -1
  57. package/dist/others/unknown-to-string.mjs.map +1 -1
  58. package/package.json +12 -12
  59. package/src/array/array-utils-modification.test.mts +93 -67
  60. package/src/array/array-utils-overload-type-error.test.mts +2 -2
  61. package/src/array/array-utils-reducing-value.test.mts +31 -37
  62. package/src/array/array-utils-slice-clamped.test.mts +94 -70
  63. package/src/array/array-utils-transformation.test.mts +557 -10
  64. package/src/array/array-utils.mts +1835 -1000
  65. package/src/array/index.mts +0 -1
  66. package/src/collections/queue.mts +2 -2
  67. package/src/collections/stack.mts +8 -8
  68. package/src/functional/match.mts +18 -44
  69. package/src/functional/optional.mts +88 -102
  70. package/src/functional/pipe.mts +25 -20
  71. package/src/functional/result.mts +114 -124
  72. package/src/globals.d.mts +10 -9
  73. package/src/iterator/range.mts +14 -17
  74. package/src/number/num.mts +16 -12
  75. package/src/object/object.mts +30 -45
  76. package/src/others/map-nullable.mts +13 -15
  77. package/dist/array/tuple-utils.d.mts +0 -421
  78. package/dist/array/tuple-utils.d.mts.map +0 -1
  79. package/dist/array/tuple-utils.mjs +0 -391
  80. package/dist/array/tuple-utils.mjs.map +0 -1
  81. package/src/array/tuple-utils.mts +0 -519
  82. package/src/array/tuple-utils.test.mts +0 -518
@@ -359,20 +359,16 @@ export namespace Result {
359
359
  * };
360
360
  * ```
361
361
  */
362
- export const unwrapOk: UnwrapOkFnOverload = (<R extends Base>(
363
- result: R,
364
- ): UnwrapOk<R> | undefined =>
365
- isErr(result)
366
- ? undefined
367
- : // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
368
- (result.value as UnwrapOk<R>)) as UnwrapOkFnOverload;
362
+ export function unwrapOk<R extends Ok<unknown>>(result: R): UnwrapOk<R>;
369
363
 
370
- type UnwrapOkFnOverload = {
371
- <R extends Ok<unknown>>(result: R): UnwrapOk<R>;
364
+ export function unwrapOk<R extends Base>(result: R): UnwrapOk<R> | undefined;
372
365
 
373
- // Curried version
374
- <R extends Base>(result: R): UnwrapOk<R> | undefined;
375
- };
366
+ export function unwrapOk<R extends Base>(result: R): UnwrapOk<R> | undefined {
367
+ return isErr(result)
368
+ ? undefined
369
+ : // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
370
+ (result.value as UnwrapOk<R>);
371
+ }
376
372
 
377
373
  /**
378
374
  * Unwraps a `Result`, returning the success value or a default value if it is `Result.Err`.
@@ -388,12 +384,22 @@ export namespace Result {
388
384
  * console.log(value); // 42
389
385
  * ```
390
386
  */
391
- export const unwrapOkOr: UnwrapOkOrFnOverload = (<R extends Base, D>(
387
+ export function unwrapOkOr<R extends Base, D>(
388
+ result: R,
389
+ defaultValue: D,
390
+ ): D | UnwrapOk<R>;
391
+
392
+ // Curried version
393
+ export function unwrapOkOr<S, D>(
394
+ defaultValue: D,
395
+ ): <E>(result: Result<S, E>) => D | S;
396
+
397
+ export function unwrapOkOr<R extends Base, D>(
392
398
  ...args: readonly [result: R, defaultValue: D] | readonly [defaultValue: D]
393
399
  ):
394
400
  | D
395
401
  | UnwrapOk<R>
396
- | (<E>(result: Result<UnwrapOk<R>, E>) => D | UnwrapOk<R>) => {
402
+ | (<E>(result: Result<UnwrapOk<R>, E>) => D | UnwrapOk<R>) {
397
403
  switch (args.length) {
398
404
  case 2: {
399
405
  // Direct version: first argument is result
@@ -409,14 +415,7 @@ export namespace Result {
409
415
  unwrapOkOr(result, defaultValue);
410
416
  }
411
417
  }
412
- }) as UnwrapOkOrFnOverload;
413
-
414
- type UnwrapOkOrFnOverload = {
415
- <R extends Base, D>(result: R, defaultValue: D): D | UnwrapOk<R>;
416
-
417
- // Curried version
418
- <S, D>(defaultValue: D): <E>(result: Result<S, E>) => D | S;
419
- };
418
+ }
420
419
 
421
420
  /**
422
421
  * Unwraps a `Result`, returning the error value.
@@ -498,12 +497,22 @@ export namespace Result {
498
497
  * console.log(error); // "failed"
499
498
  * ```
500
499
  */
501
- export const unwrapErrOr: UnwrapErrOrFnOverload = (<R extends Base, D>(
500
+ export function unwrapErrOr<R extends Base, D>(
501
+ result: R,
502
+ defaultValue: D,
503
+ ): D | UnwrapErr<R>;
504
+
505
+ // Curried version
506
+ export function unwrapErrOr<E, D>(
507
+ defaultValue: D,
508
+ ): <S>(result: Result<S, E>) => D | E;
509
+
510
+ export function unwrapErrOr<R extends Base, D>(
502
511
  ...args: readonly [result: R, defaultValue: D] | readonly [defaultValue: D]
503
512
  ):
504
513
  | D
505
514
  | UnwrapErr<R>
506
- | (<S>(result: Result<S, UnwrapErr<R>>) => D | UnwrapErr<R>) => {
515
+ | (<S>(result: Result<S, UnwrapErr<R>>) => D | UnwrapErr<R>) {
507
516
  switch (args.length) {
508
517
  case 2: {
509
518
  // Direct version: first argument is result
@@ -519,14 +528,7 @@ export namespace Result {
519
528
  unwrapErrOr(result, defaultValue);
520
529
  }
521
530
  }
522
- }) as UnwrapErrOrFnOverload;
523
-
524
- type UnwrapErrOrFnOverload = {
525
- <R extends Base, D>(result: R, defaultValue: D): D | UnwrapErr<R>;
526
-
527
- // Curried version
528
- <E, D>(defaultValue: D): <S>(result: Result<S, E>) => D | E;
529
- };
531
+ }
530
532
 
531
533
  /**
532
534
  * Maps a `Result<S, E>` to `Result<S2, E>` by applying a function to the success value.
@@ -549,12 +551,21 @@ export namespace Result {
549
551
  * console.log(Result.unwrap(result2)); // 10
550
552
  * ```
551
553
  */
552
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
553
- export const map: MapFnOverload = (<R extends Base, S2>(
554
+ export function map<R extends Base, S2>(
555
+ result: R,
556
+ mapFn: (value: UnwrapOk<R>) => S2,
557
+ ): Result<S2, UnwrapErr<R>>;
558
+
559
+ // Curried version
560
+ export function map<S, S2>(
561
+ mapFn: (value: S) => S2,
562
+ ): <E>(result: Result<S, E>) => Result<S2, E>;
563
+
564
+ export function map<R extends Base, S2>(
554
565
  ...args:
555
566
  | readonly [result: R, mapFn: (value: UnwrapOk<R>) => S2]
556
567
  | readonly [mapFn: (value: UnwrapOk<R>) => S2]
557
- ): Result<S2, UnwrapErr<R>> | ((result: R) => Result<S2, UnwrapErr<R>>) => {
568
+ ): Result<S2, UnwrapErr<R>> | ((result: R) => Result<S2, UnwrapErr<R>>) {
558
569
  switch (args.length) {
559
570
  case 2: {
560
571
  const [result, mapFn] = args;
@@ -571,19 +582,7 @@ export namespace Result {
571
582
  return (result: R) => map(result, mapFn);
572
583
  }
573
584
  }
574
- }) as MapFnOverload;
575
-
576
- type MapFnOverload = {
577
- <R extends Base, S2>(
578
- result: R,
579
- mapFn: (value: UnwrapOk<R>) => S2,
580
- ): Result<S2, UnwrapErr<R>>;
581
-
582
- // Curried version
583
- <S, S2>(
584
- mapFn: (value: S) => S2,
585
- ): <E>(result: Result<S, E>) => Result<S2, E>;
586
- };
585
+ }
587
586
 
588
587
  /**
589
588
  * Maps a `Result<S, E>` to `Result<S, E2>` by applying a function to the error value.
@@ -600,12 +599,21 @@ export namespace Result {
600
599
  * console.log(Result.unwrapErr(mapped)); // "ERROR"
601
600
  * ```
602
601
  */
603
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
604
- export const mapErr: MapErrFnOverload = (<R extends Base, E2>(
602
+ export function mapErr<R extends Base, E2>(
603
+ result: R,
604
+ mapFn: (error: UnwrapErr<R>) => E2,
605
+ ): Result<UnwrapOk<R>, E2>;
606
+
607
+ // Curried version
608
+ export function mapErr<E, E2>(
609
+ mapFn: (error: E) => E2,
610
+ ): <S>(result: Result<S, E>) => Result<S, E2>;
611
+
612
+ export function mapErr<R extends Base, E2>(
605
613
  ...args:
606
614
  | readonly [result: R, mapFn: (error: UnwrapErr<R>) => E2]
607
615
  | readonly [mapFn: (error: UnwrapErr<R>) => E2]
608
- ): Result<UnwrapOk<R>, E2> | ((result: R) => Result<UnwrapOk<R>, E2>) => {
616
+ ): Result<UnwrapOk<R>, E2> | ((result: R) => Result<UnwrapOk<R>, E2>) {
609
617
  switch (args.length) {
610
618
  case 2: {
611
619
  const [result, mapFn] = args;
@@ -622,19 +630,7 @@ export namespace Result {
622
630
  return (result: R) => mapErr(result, mapFn);
623
631
  }
624
632
  }
625
- }) as MapErrFnOverload;
626
-
627
- type MapErrFnOverload = {
628
- <R extends Base, E2>(
629
- result: R,
630
- mapFn: (error: UnwrapErr<R>) => E2,
631
- ): Result<UnwrapOk<R>, E2>;
632
-
633
- // Curried version
634
- <E, E2>(
635
- mapFn: (error: E) => E2,
636
- ): <S>(result: Result<S, E>) => Result<S, E2>;
637
- };
633
+ }
638
634
 
639
635
  /**
640
636
  * Applies one of two functions depending on whether the `Result` is `Ok` or `Err`.
@@ -652,8 +648,19 @@ export namespace Result {
652
648
  * console.log(Result.unwrapOk(folded)); // 84
653
649
  * ```
654
650
  */
655
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
656
- export const fold: FoldFnOverload = (<R extends Base, S2, E2>(
651
+ export function fold<R extends Base, S2, E2>(
652
+ result: R,
653
+ mapFn: (value: UnwrapOk<R>) => S2,
654
+ mapErrFn: (error: UnwrapErr<R>) => E2,
655
+ ): Result<S2, E2>;
656
+
657
+ // Curried version
658
+ export function fold<S, E, S2, E2>(
659
+ mapFn: (value: S) => S2,
660
+ mapErrFn: (error: E) => E2,
661
+ ): (result: Result<S, E>) => Result<S2, E2>;
662
+
663
+ export function fold<R extends Base, S2, E2>(
657
664
  ...args:
658
665
  | readonly [
659
666
  result: R,
@@ -666,7 +673,7 @@ export namespace Result {
666
673
  ]
667
674
  ):
668
675
  | Result<S2, E2>
669
- | ((result: Result<UnwrapOk<R>, UnwrapErr<R>>) => Result<S2, E2>) => {
676
+ | ((result: Result<UnwrapOk<R>, UnwrapErr<R>>) => Result<S2, E2>) {
670
677
  switch (args.length) {
671
678
  case 3: {
672
679
  const [result, mapFn, mapErrFn] = args;
@@ -683,21 +690,7 @@ export namespace Result {
683
690
  isOk(result) ? ok(mapFn(result.value)) : err(mapErrFn(result.value));
684
691
  }
685
692
  }
686
- }) as FoldFnOverload;
687
-
688
- type FoldFnOverload = {
689
- <R extends Base, S2, E2>(
690
- result: R,
691
- mapFn: (value: UnwrapOk<R>) => S2,
692
- mapErrFn: (error: UnwrapErr<R>) => E2,
693
- ): Result<S2, E2>;
694
-
695
- // Curried version
696
- <S, E, S2, E2>(
697
- mapFn: (value: S) => S2,
698
- mapErrFn: (error: E) => E2,
699
- ): (result: Result<S, E>) => Result<S2, E2>;
700
- };
693
+ }
701
694
 
702
695
  /**
703
696
  * Applies a function that returns a `Result` to the success value of a `Result`.
@@ -718,14 +711,23 @@ export namespace Result {
718
711
  * console.log(Result.unwrapOk(result)); // 5
719
712
  * ```
720
713
  */
721
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
722
- export const flatMap: FlatMapFnOverload = (<R extends Base, S2, E2>(
714
+ export function flatMap<R extends Base, S2, E2>(
715
+ result: R,
716
+ flatMapFn: (value: UnwrapOk<R>) => Result<S2, E2>,
717
+ ): Result<S2, E2 | UnwrapErr<R>>;
718
+
719
+ // Curried version
720
+ export function flatMap<S, S2, E2>(
721
+ flatMapFn: (value: S) => Result<S2, E2>,
722
+ ): <E>(result: Result<S, E>) => Result<S2, E | E2>;
723
+
724
+ export function flatMap<R extends Base, S2, E2>(
723
725
  ...args:
724
726
  | readonly [result: R, flatMapFn: (value: UnwrapOk<R>) => Result<S2, E2>]
725
727
  | readonly [flatMapFn: (value: UnwrapOk<R>) => Result<S2, E2>]
726
728
  ):
727
729
  | Result<S2, E2 | UnwrapErr<R>>
728
- | (<E>(result: Result<UnwrapOk<R>, E>) => Result<S2, E | E2>) => {
730
+ | (<E>(result: Result<UnwrapOk<R>, E>) => Result<S2, E | E2>) {
729
731
  switch (args.length) {
730
732
  case 2: {
731
733
  const [result, flatMapFn] = args;
@@ -742,19 +744,7 @@ export namespace Result {
742
744
  isErr(result) ? result : flatMapFn(result.value);
743
745
  }
744
746
  }
745
- }) as FlatMapFnOverload;
746
-
747
- type FlatMapFnOverload = {
748
- <R extends Base, S2, E2>(
749
- result: R,
750
- flatMapFn: (value: UnwrapOk<R>) => Result<S2, E2>,
751
- ): Result<S2, E2 | UnwrapErr<R>>;
752
-
753
- // Curried version
754
- <S, S2, E2>(
755
- flatMapFn: (value: S) => Result<S2, E2>,
756
- ): <E>(result: Result<S, E>) => Result<S2, E | E2>;
757
- };
747
+ }
758
748
 
759
749
  /**
760
750
  * Unwraps a `Result`, returning the success value or throwing an error with the provided message.
@@ -770,10 +760,19 @@ export namespace Result {
770
760
  * console.log(value); // 42
771
761
  * ```
772
762
  */
773
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
774
- export const expectToBe: ExpectToBeFnOverload = (<R extends Base>(
763
+ export function expectToBe<R extends Base>(
764
+ result: R,
765
+ message: string,
766
+ ): UnwrapOk<R>;
767
+
768
+ // Curried version
769
+ export function expectToBe<S>(
770
+ message: string,
771
+ ): <E>(result: Result<S, E>) => S;
772
+
773
+ export function expectToBe<R extends Base>(
775
774
  ...args: readonly [result: R, message: string] | readonly [message: string]
776
- ): UnwrapOk<R> | (<E>(result: Result<UnwrapOk<R>, E>) => UnwrapOk<R>) => {
775
+ ): UnwrapOk<R> | (<E>(result: Result<UnwrapOk<R>, E>) => UnwrapOk<R>) {
777
776
  switch (args.length) {
778
777
  case 2: {
779
778
  // Direct version: first argument is result
@@ -792,14 +791,7 @@ export namespace Result {
792
791
  expectToBe(result, message);
793
792
  }
794
793
  }
795
- }) as ExpectToBeFnOverload;
796
-
797
- type ExpectToBeFnOverload = {
798
- <R extends Base>(result: R, message: string): UnwrapOk<R>;
799
-
800
- // Curried version
801
- <S>(message: string): <E>(result: Result<S, E>) => S;
802
- };
794
+ }
803
795
 
804
796
  /**
805
797
  * @internal
@@ -933,13 +925,23 @@ export namespace Result {
933
925
  * console.log(Result.unwrapOk(result)); // "default"
934
926
  * ```
935
927
  */
936
- export const orElse: OrElseFnOverload = (<R extends Base, R2 extends Base>(
928
+ export function orElse<R extends Base, R2 extends Base>(
929
+ result: R,
930
+ alternative: R2,
931
+ ): NarrowToOk<R> | R2;
932
+
933
+ // Curried version
934
+ export function orElse<S, E, S2, E2>(
935
+ alternative: Result<S2, E2>,
936
+ ): (result: Result<S, E>) => Result<S, E> | Result<S2, E2>;
937
+
938
+ export function orElse<R extends Base, R2 extends Base>(
937
939
  ...args: readonly [result: R, alternative: R2] | readonly [alternative: R2]
938
940
  ):
939
941
  | (NarrowToOk<R> | R2)
940
942
  | ((
941
943
  result: Result<UnwrapOk<R>, UnwrapErr<R>>,
942
- ) => Result<UnwrapOk<R>, UnwrapErr<R>> | R2) => {
944
+ ) => Result<UnwrapOk<R>, UnwrapErr<R>> | R2) {
943
945
  switch (args.length) {
944
946
  case 2: {
945
947
  const [result, alternative] = args;
@@ -953,19 +955,7 @@ export namespace Result {
953
955
  orElse(result, alternative);
954
956
  }
955
957
  }
956
- }) as OrElseFnOverload;
957
-
958
- type OrElseFnOverload = {
959
- <R extends Base, R2 extends Base>(
960
- result: R,
961
- alternative: R2,
962
- ): NarrowToOk<R> | R2;
963
-
964
- // Curried version
965
- <S, E, S2, E2>(
966
- alternative: Result<S2, E2>,
967
- ): (result: Result<S, E>) => Result<S, E> | Result<S2, E2>;
968
- };
958
+ }
969
959
 
970
960
  /**
971
961
  * Combines two `Result` values into a single `Result` containing a tuple.
package/src/globals.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  /// <reference types="ts-type-forge" />
2
2
 
3
- type SmallUint = SmallInt<'>=0'>;
4
- type PositiveSmallInt = SmallInt<'>0'>;
3
+ type SmallPositiveInt = WithSmallInt<PositiveInt>;
5
4
 
6
5
  /**
7
6
  * Represents the type of keys that can be used in a standard JavaScript Map.
@@ -22,17 +21,19 @@ declare namespace SizeType {
22
21
  type TypedArraySearchResult = TypedArray | -1;
23
22
  type StrSearchResult = Str | -1;
24
23
 
25
- type ArgArr = WithSmallInt<NormalizeBrandUnion<NegativeInt32 | Arr>>;
26
- type ArgTypedArray = WithSmallInt<SafeInt>;
27
- type ArgStr = WithSmallInt<SafeInt>;
24
+ type ArgArr = WithSmallInt<Arr>;
25
+ type ArgTypedArray = WithSmallInt<TypedArray>;
26
+ type ArgStr = WithSmallInt<Str>;
27
+
28
+ type ArgArrWithNegative = WithSmallInt<
29
+ NormalizeBrandUnion<NegativeInt32 | Arr>
30
+ >;
31
+ type ArgTypedArrayWithNegative = WithSmallInt<SafeInt>;
32
+ type ArgStrWithNegative = WithSmallInt<SafeInt>;
28
33
 
29
34
  type ArgArrPositive = WithSmallInt<IntersectBrand<PositiveNumber, Arr>>;
30
35
  type ArgTypedArrayPositive = WithSmallInt<
31
36
  IntersectBrand<PositiveNumber, TypedArray>
32
37
  >;
33
38
  type ArgStrPositive = WithSmallInt<IntersectBrand<PositiveNumber, Str>>;
34
-
35
- type ArgArrNonNegative = WithSmallInt<Arr>;
36
- type ArgTypedArrayNonNegative = WithSmallInt<TypedArray>;
37
- type ArgStrNonNegative = WithSmallInt<Str>;
38
39
  }
@@ -90,8 +90,19 @@ import { SafeInt, asSafeInt } from '../number/index.mjs';
90
90
  * }
91
91
  * ```
92
92
  */
93
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
94
- export const range: RangeFnOverload = function* (
93
+ export function range(
94
+ start: SafeUintWithSmallInt,
95
+ end: SafeUintWithSmallInt,
96
+ step?: PositiveSafeIntWithSmallInt,
97
+ ): Generator<SafeUint, void, unknown>;
98
+
99
+ export function range(
100
+ start: SafeIntWithSmallInt,
101
+ end: SafeIntWithSmallInt,
102
+ step?: NonZeroSafeIntWithSmallInt,
103
+ ): Generator<SafeInt, void, unknown>;
104
+
105
+ export function* range(
95
106
  start: SafeIntWithSmallInt,
96
107
  end: SafeIntWithSmallInt,
97
108
  step: NonZeroSafeIntWithSmallInt = 1,
@@ -103,18 +114,4 @@ export const range: RangeFnOverload = function* (
103
114
  ) {
104
115
  yield mut_i;
105
116
  }
106
- } as RangeFnOverload;
107
-
108
- type RangeFnOverload = {
109
- (
110
- start: SafeUintWithSmallInt,
111
- end: SafeUintWithSmallInt,
112
- step?: PositiveSafeIntWithSmallInt,
113
- ): Generator<SafeUint, void, unknown>;
114
-
115
- (
116
- start: SafeIntWithSmallInt,
117
- end: SafeIntWithSmallInt,
118
- step?: NonZeroSafeIntWithSmallInt,
119
- ): Generator<SafeInt, void, unknown>;
120
- };
117
+ }
@@ -288,12 +288,23 @@ export namespace Num {
288
288
  * clampToPercent(150); // 100
289
289
  * ```
290
290
  */
291
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
292
- export const clamp: ClampFnOverload = ((
291
+ export function clamp(
292
+ target: number,
293
+ lowerBound: number,
294
+ upperBound: number,
295
+ ): number;
296
+
297
+ // Curried version
298
+ export function clamp(
299
+ lowerBound: number,
300
+ upperBound: number,
301
+ ): (target: number) => number;
302
+
303
+ export function clamp(
293
304
  ...args:
294
305
  | readonly [target: number, lowerBound: number, upperBound: number]
295
306
  | readonly [lowerBound: number, upperBound: number]
296
- ) => {
307
+ ): number | ((target: number) => number) {
297
308
  switch (args.length) {
298
309
  case 3: {
299
310
  const [target, lowerBound, upperBound] = args;
@@ -308,14 +319,7 @@ export namespace Num {
308
319
  clamp(target, lowerBound, upperBound);
309
320
  }
310
321
  }
311
- }) as ClampFnOverload;
312
-
313
- type ClampFnOverload = {
314
- (target: number, lowerBound: number, upperBound: number): number;
315
-
316
- // Curried version
317
- (lowerBound: number, upperBound: number): (target: number) => number;
318
- };
322
+ }
319
323
 
320
324
  /**
321
325
  * Performs type-safe division with compile-time zero-check.
@@ -503,7 +507,7 @@ export namespace Num {
503
507
  * const two = Num.decrement(three); // type is 2, value is 2
504
508
  * ```
505
509
  */
506
- export const decrement = <N extends PositiveSmallInt>(n: N): Decrement<N> =>
510
+ export const decrement = <N extends SmallPositiveInt>(n: N): Decrement<N> =>
507
511
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
508
512
  (n - 1) as Decrement<N>;
509
513
  }
@@ -113,17 +113,26 @@ export namespace Obj {
113
113
  * const visible = pickVisible(partialUser); // { name: "Alice" } (age omitted)
114
114
  * ```
115
115
  */
116
- export const pick: // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
117
- PickFnOverload = (<
116
+ export function pick<
117
+ const R extends UnknownRecord,
118
+ const Keys extends readonly (keyof R)[],
119
+ >(record: R, keys: Keys): Pick<R, ArrayElement<Keys>>;
120
+
121
+ // Curried version
122
+ export function pick<const Keys extends readonly PropertyKey[]>(
123
+ keys: Keys,
124
+ ): <const R extends UnknownRecord>(
125
+ record: R,
126
+ ) => RelaxedPick<R, ArrayElement<Keys>>;
127
+
128
+ export function pick<
118
129
  const R extends UnknownRecord,
119
130
  const Keys extends readonly (keyof R)[],
120
131
  >(
121
- ...args:
122
- | readonly [record: R, keys: Keys]
123
- | readonly [keys: readonly PropertyKey[]]
132
+ ...args: readonly [record: R, keys: Keys] | readonly [keys: Keys]
124
133
  ):
125
134
  | Pick<R, ArrayElement<Keys>>
126
- | ((record: R) => RelaxedPick<R, ArrayElement<Keys>>) => {
135
+ | ((record: R) => RelaxedPick<R, ArrayElement<Keys>>) {
127
136
  switch (args.length) {
128
137
  case 2: {
129
138
  const [record, keys] = args;
@@ -139,29 +148,10 @@ export namespace Obj {
139
148
 
140
149
  case 1: {
141
150
  const [keys] = args;
142
- return <R2 extends UnknownRecord>(record: R2) =>
143
- pick(
144
- record,
145
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
146
- keys as readonly (keyof R2)[],
147
- );
151
+ return (record: R) => pick(record, keys);
148
152
  }
149
153
  }
150
- }) as PickFnOverload;
151
-
152
- type PickFnOverload = {
153
- <const R extends UnknownRecord, const Keys extends readonly (keyof R)[]>(
154
- record: R,
155
- keys: Keys,
156
- ): Pick<R, ArrayElement<Keys>>;
157
-
158
- // Curried version
159
- <const Keys extends readonly PropertyKey[]>(
160
- keys: Keys,
161
- ): <const R extends UnknownRecord>(
162
- record: R,
163
- ) => RelaxedPick<R, ArrayElement<Keys>>;
164
- };
154
+ }
165
155
 
166
156
  /**
167
157
  * Creates a new record that excludes the specified keys from the source record.
@@ -236,8 +226,17 @@ export namespace Obj {
236
226
  * const cleaned = omitCredentials(partialUser); // { id: 1, name: "Alice" }
237
227
  * ```
238
228
  */
239
- export const omit: // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
240
- OmitFnOverload = (<
229
+ export function omit<
230
+ const R extends UnknownRecord,
231
+ const Keys extends readonly (keyof R)[],
232
+ >(record: R, keys: Keys): Omit<R, ArrayElement<Keys>>;
233
+
234
+ // Curried version
235
+ export function omit<const Keys extends readonly PropertyKey[]>(
236
+ keys: Keys,
237
+ ): <const R extends UnknownRecord>(record: R) => Omit<R, ArrayElement<Keys>>;
238
+
239
+ export function omit<
241
240
  const R extends UnknownRecord,
242
241
  const Keys extends readonly (keyof R)[],
243
242
  >(
@@ -246,7 +245,7 @@ export namespace Obj {
246
245
  | readonly [keys: readonly PropertyKey[]]
247
246
  ):
248
247
  | Omit<R, ArrayElement<Keys>>
249
- | ((record: R) => Omit<R, ArrayElement<Keys>>) => {
248
+ | ((record: R) => Omit<R, ArrayElement<Keys>>) {
250
249
  switch (args.length) {
251
250
  case 2: {
252
251
  const [record, keys] = args;
@@ -272,21 +271,7 @@ export namespace Obj {
272
271
  };
273
272
  }
274
273
  }
275
- }) as OmitFnOverload;
276
-
277
- type OmitFnOverload = {
278
- <const R extends UnknownRecord, const Keys extends readonly (keyof R)[]>(
279
- record: R,
280
- keys: Keys,
281
- ): Omit<R, ArrayElement<Keys>>;
282
-
283
- // Curried version
284
- <const Keys extends readonly PropertyKey[]>(
285
- keys: Keys,
286
- ): <const R extends UnknownRecord>(
287
- record: R,
288
- ) => Omit<R, ArrayElement<Keys>>;
289
- };
274
+ }
290
275
 
291
276
  /**
292
277
  * Creates an object from an array of key-value pairs with precise TypeScript typing.
@@ -142,11 +142,21 @@
142
142
  * @see Optional - For more complex optional value handling
143
143
  * @see Result - For error handling with detailed error information
144
144
  */
145
- export const mapNullable: MapNullableFnOverload = (<const A, const B>(
145
+ export function mapNullable<const A, const B>(
146
+ value: A | null | undefined,
147
+ mapFn: (v: A) => B,
148
+ ): B | undefined;
149
+
150
+ // Curried version
151
+ export function mapNullable<const A, const B>(
152
+ mapFn: (v: A) => B,
153
+ ): (value: A | null | undefined) => B | undefined;
154
+
155
+ export function mapNullable<const A, const B>(
146
156
  ...args:
147
157
  | readonly [value: A | null | undefined, mapFn: (v: A) => B]
148
158
  | readonly [mapFn: (v: A) => B]
149
- ): (B | undefined) | ((value: A | null | undefined) => B | undefined) => {
159
+ ): (B | undefined) | ((value: A | null | undefined) => B | undefined) {
150
160
  switch (args.length) {
151
161
  case 2: {
152
162
  const [value, mapFn] = args;
@@ -157,16 +167,4 @@ export const mapNullable: MapNullableFnOverload = (<const A, const B>(
157
167
  return (value: A | null | undefined) => mapNullable(value, mapFn);
158
168
  }
159
169
  }
160
- }) as MapNullableFnOverload;
161
-
162
- type MapNullableFnOverload = {
163
- <const A, const B>(
164
- value: A | null | undefined,
165
- mapFn: (v: A) => B,
166
- ): B | undefined;
167
-
168
- // Curried version
169
- <const A, const B>(
170
- mapFn: (v: A) => B,
171
- ): (value: A | null | undefined) => B | undefined;
172
- };
170
+ }