ts-data-forge 1.5.0 → 1.5.2

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 (68) hide show
  1. package/dist/array/array-utils.d.mts +137 -358
  2. package/dist/array/array-utils.d.mts.map +1 -1
  3. package/dist/array/array-utils.mjs +191 -1966
  4. package/dist/array/array-utils.mjs.map +1 -1
  5. package/dist/array/tuple-utils.d.mts +9 -23
  6. package/dist/array/tuple-utils.d.mts.map +1 -1
  7. package/dist/array/tuple-utils.mjs +10 -56
  8. package/dist/array/tuple-utils.mjs.map +1 -1
  9. package/dist/collections/imap-mapped.mjs.map +1 -1
  10. package/dist/collections/imap.mjs.map +1 -1
  11. package/dist/collections/iset-mapped.mjs.map +1 -1
  12. package/dist/collections/iset.mjs.map +1 -1
  13. package/dist/collections/queue.mjs.map +1 -1
  14. package/dist/collections/stack.mjs.map +1 -1
  15. package/dist/functional/match.d.mts +2 -33
  16. package/dist/functional/match.d.mts.map +1 -1
  17. package/dist/functional/match.mjs +2 -119
  18. package/dist/functional/match.mjs.map +1 -1
  19. package/dist/functional/optional.d.mts +34 -197
  20. package/dist/functional/optional.d.mts.map +1 -1
  21. package/dist/functional/optional.mjs +40 -312
  22. package/dist/functional/optional.mjs.map +1 -1
  23. package/dist/functional/pipe.d.mts +2 -15
  24. package/dist/functional/pipe.d.mts.map +1 -1
  25. package/dist/functional/pipe.mjs +2 -110
  26. package/dist/functional/pipe.mjs.map +1 -1
  27. package/dist/functional/result.d.mts +18 -209
  28. package/dist/functional/result.d.mts.map +1 -1
  29. package/dist/functional/result.mjs +40 -360
  30. package/dist/functional/result.mjs.map +1 -1
  31. package/dist/guard/has-key.d.mts +1 -1
  32. package/dist/guard/has-key.mjs +1 -1
  33. package/dist/iterator/range.d.mts +2 -6
  34. package/dist/iterator/range.d.mts.map +1 -1
  35. package/dist/iterator/range.mjs +2 -93
  36. package/dist/iterator/range.mjs.map +1 -1
  37. package/dist/json/json.d.mts +14 -438
  38. package/dist/json/json.d.mts.map +1 -1
  39. package/dist/json/json.mjs +14 -438
  40. package/dist/json/json.mjs.map +1 -1
  41. package/dist/number/num.d.mts +7 -107
  42. package/dist/number/num.d.mts.map +1 -1
  43. package/dist/number/num.mjs +7 -122
  44. package/dist/number/num.mjs.map +1 -1
  45. package/dist/number/refined-number-utils.mjs.map +1 -1
  46. package/dist/object/object.d.mts +4 -10
  47. package/dist/object/object.d.mts.map +1 -1
  48. package/dist/object/object.mjs +8 -140
  49. package/dist/object/object.mjs.map +1 -1
  50. package/dist/others/map-nullable.d.mts +2 -6
  51. package/dist/others/map-nullable.d.mts.map +1 -1
  52. package/dist/others/map-nullable.mjs +2 -146
  53. package/dist/others/map-nullable.mjs.map +1 -1
  54. package/dist/others/memoize-function.mjs.map +1 -1
  55. package/dist/others/unknown-to-string.mjs.map +1 -1
  56. package/package.json +11 -11
  57. package/src/array/array-utils.mts +707 -881
  58. package/src/array/tuple-utils.mts +20 -41
  59. package/src/functional/match.mts +18 -44
  60. package/src/functional/optional.mts +93 -248
  61. package/src/functional/pipe.mts +25 -20
  62. package/src/functional/result.mts +114 -288
  63. package/src/guard/has-key.mts +1 -1
  64. package/src/iterator/range.mts +14 -17
  65. package/src/json/json.mts +14 -438
  66. package/src/number/num.mts +20 -113
  67. package/src/object/object.mts +30 -45
  68. package/src/others/map-nullable.mts +13 -15
@@ -103,18 +103,15 @@ export namespace Arr {
103
103
  * @see {@link isEmpty} for checking if size is 0
104
104
  * @see {@link isNonEmpty} for checking if size > 0
105
105
  */
106
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
107
- export const size: SizeFnOverload = (<Ar extends readonly unknown[]>(
106
+ export function size<Ar extends NonEmptyArray<unknown>>(
108
107
  array: Ar,
109
- ): SizeType.Arr => asUint32(array.length)) as SizeFnOverload;
108
+ ): IntersectBrand<PositiveNumber, SizeType.Arr>;
110
109
 
111
- type SizeFnOverload = {
112
- <Ar extends NonEmptyArray<unknown>>(
113
- array: Ar,
114
- ): IntersectBrand<PositiveNumber, SizeType.Arr>;
110
+ export function size<Ar extends readonly unknown[]>(array: Ar): SizeType.Arr;
115
111
 
116
- <Ar extends readonly unknown[]>(array: Ar): SizeType.Arr;
117
- };
112
+ export function size<Ar extends readonly unknown[]>(array: Ar): SizeType.Arr {
113
+ return asUint32(array.length);
114
+ }
118
115
 
119
116
  export const length = size;
120
117
 
@@ -440,27 +437,24 @@ export namespace Arr {
440
437
  * expectType<typeof maybeEmpty, readonly 0[]>('=');
441
438
  * ```
442
439
  */
443
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
444
- export const zeros: ZerosFnOverload = ((
445
- len: SizeType.ArgArrNonNegative,
446
- ): readonly 0[] => Array.from<0>({ length: len }).fill(0)) as ZerosFnOverload;
447
-
448
- type ZerosFnOverload = {
449
- /**
450
- * Create array of zeros with compile-time length.
451
- */
452
- <N extends SmallUint>(len: N): ArrayOfLength<N, 0>;
453
-
454
- /**
455
- * Create non-empty array of zeros.
456
- */
457
- (len: SizeType.ArgArrPositive): NonEmptyArray<0>;
458
-
459
- /**
460
- * Create array of zeros.
461
- */
462
- (len: SizeType.ArgArrNonNegative): readonly 0[];
463
- };
440
+ /**
441
+ * Create array of zeros with compile-time length.
442
+ */
443
+ export function zeros<N extends SmallUint>(len: N): ArrayOfLength<N, 0>;
444
+
445
+ /**
446
+ * Create non-empty array of zeros.
447
+ */
448
+ export function zeros(len: SizeType.ArgArrPositive): NonEmptyArray<0>;
449
+
450
+ /**
451
+ * Create array of zeros.
452
+ */
453
+ export function zeros(len: SizeType.ArgArrNonNegative): readonly 0[];
454
+
455
+ export function zeros(len: SizeType.ArgArrNonNegative): readonly 0[] {
456
+ return Array.from<0>({ length: len }).fill(0);
457
+ }
464
458
 
465
459
  /**
466
460
  * Creates a sequence of consecutive integers from 0 to `len-1`.
@@ -503,19 +497,19 @@ export namespace Arr {
503
497
  * expectType<typeof single, readonly [0]>('=');
504
498
  * ```
505
499
  */
506
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
507
- export const seq: SeqFnOverload = ((
508
- len: SizeType.ArgArrNonNegative,
509
- ): readonly SizeType.Arr[] =>
510
- Array.from({ length: len }, (_, i) => asUint32(i))) as SeqFnOverload;
500
+ export function seq<N extends SmallUint>(len: N): Seq<N>;
511
501
 
512
- type SeqFnOverload = {
513
- <N extends SmallUint>(len: N): Seq<N>;
502
+ export function seq(
503
+ len: SizeType.ArgArrPositive,
504
+ ): NonEmptyArray<SizeType.Arr>;
514
505
 
515
- (len: SizeType.ArgArrPositive): NonEmptyArray<SizeType.Arr>;
506
+ export function seq(len: SizeType.ArgArrNonNegative): readonly SizeType.Arr[];
516
507
 
517
- (len: SizeType.ArgArrNonNegative): readonly SizeType.Arr[];
518
- };
508
+ export function seq(
509
+ len: SizeType.ArgArrNonNegative,
510
+ ): readonly SizeType.Arr[] {
511
+ return Array.from({ length: len }, (_, i) => asUint32(i));
512
+ }
519
513
 
520
514
  /**
521
515
  * Creates a new array of the specified length, with each position filled with the provided initial value.
@@ -565,20 +559,27 @@ export namespace Arr {
565
559
  * @see {@link zeros} for creating arrays filled with zeros
566
560
  * @see {@link seq} for creating sequences of consecutive integers
567
561
  */
568
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
569
- export const create: CreateFnOverload = (<const V,>(
570
- len: SizeType.ArgArrNonNegative,
562
+ export function create<const V, N extends SmallUint>(
563
+ len: N,
571
564
  init: V,
572
- ): readonly V[] =>
573
- Array.from({ length: Math.max(0, len) }, () => init)) as CreateFnOverload;
565
+ ): ArrayOfLength<N, V>;
574
566
 
575
- type CreateFnOverload = {
576
- <const V, N extends SmallUint>(len: N, init: V): ArrayOfLength<N, V>;
567
+ export function create<const V>(
568
+ len: SizeType.ArgArrPositive,
569
+ init: V,
570
+ ): NonEmptyArray<V>;
577
571
 
578
- <const V>(len: SizeType.ArgArrPositive, init: V): NonEmptyArray<V>;
572
+ export function create<const V>(
573
+ len: SizeType.ArgArrNonNegative,
574
+ init: V,
575
+ ): readonly V[];
579
576
 
580
- <const V>(len: SizeType.ArgArrNonNegative, init: V): readonly V[];
581
- };
577
+ export function create<const V>(
578
+ len: SizeType.ArgArrNonNegative,
579
+ init: V,
580
+ ): readonly V[] {
581
+ return Array.from({ length: Math.max(0, len) }, () => init);
582
+ }
582
583
 
583
584
  export const newArray = create;
584
585
 
@@ -803,33 +804,31 @@ export namespace Arr {
803
804
  * @see {@link SmallUint} for understanding the constraint that enables precise typing
804
805
  * @see {@link SafeInt} and {@link SafeUint} for the safe integer types used
805
806
  */
806
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
807
- export const range: RangeFnOverload = ((
807
+ export function range<S extends SmallUint, E extends SmallUint>(
808
+ start: S,
809
+ end: E,
810
+ step?: 1,
811
+ ): RangeList<S, E>;
812
+
813
+ export function range(
814
+ start: SafeUintWithSmallInt,
815
+ end: SafeUintWithSmallInt,
816
+ step?: PositiveSafeIntWithSmallInt,
817
+ ): readonly SafeUint[];
818
+
819
+ export function range(
820
+ start: SafeIntWithSmallInt,
821
+ end: SafeIntWithSmallInt,
822
+ step?: NonZeroSafeIntWithSmallInt,
823
+ ): readonly SafeInt[];
824
+
825
+ export function range(
808
826
  start: SafeIntWithSmallInt,
809
827
  end: SafeIntWithSmallInt,
810
828
  step: NonZeroSafeIntWithSmallInt = 1,
811
- ): readonly SafeInt[] =>
812
- Array.from(rangeIterator(start, end, step))) as RangeFnOverload;
813
-
814
- type RangeFnOverload = {
815
- <S extends SmallUint, E extends SmallUint>(
816
- start: S,
817
- end: E,
818
- step?: 1,
819
- ): RangeList<S, E>;
820
-
821
- (
822
- start: SafeUintWithSmallInt,
823
- end: SafeUintWithSmallInt,
824
- step?: PositiveSafeIntWithSmallInt,
825
- ): readonly SafeUint[];
826
-
827
- (
828
- start: SafeIntWithSmallInt,
829
- end: SafeIntWithSmallInt,
830
- step?: NonZeroSafeIntWithSmallInt,
831
- ): readonly SafeInt[];
832
- };
829
+ ): readonly SafeInt[] {
830
+ return Array.from(rangeIterator(start, end, step));
831
+ }
833
832
 
834
833
  // element access
835
834
 
@@ -943,12 +942,22 @@ export namespace Arr {
943
942
  * @see {@link Optional.unwrapOr} for safe unwrapping with defaults
944
943
  * @see {@link Optional.map} for transforming Optional values
945
944
  */
946
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
947
- export const at: AtFnOverload = (<E,>(
945
+ export function at<E>(
946
+ array: readonly E[],
947
+ index: SizeType.ArgArr,
948
+ ): Optional<E>;
949
+
950
+ // Curried version
951
+
952
+ export function at(
953
+ index: SizeType.ArgArr,
954
+ ): <E>(array: readonly E[]) => Optional<E>;
955
+
956
+ export function at<E>(
948
957
  ...args:
949
958
  | readonly [array: readonly E[], index: SizeType.ArgArr]
950
959
  | readonly [index: SizeType.ArgArr]
951
- ): Optional<E> | (<E2>(array: readonly E2[]) => Optional<E2>) => {
960
+ ): Optional<E> | ((array: readonly E[]) => Optional<E>) {
952
961
  switch (args.length) {
953
962
  case 2: {
954
963
  const [array, index] = args;
@@ -962,20 +971,10 @@ export namespace Arr {
962
971
  }
963
972
  case 1: {
964
973
  const [index] = args;
965
- return <E2,>(array: readonly E2[]) => at(array, index);
974
+ return (array: readonly E[]) => at(array, index);
966
975
  }
967
976
  }
968
- }) as AtFnOverload;
969
-
970
- /**
971
- * Function type for safely accessing an array element at a given index.
972
- */
973
- type AtFnOverload = {
974
- <E>(array: readonly E[], index: SizeType.ArgArr): Optional<E>;
975
-
976
- // Curried version
977
- (index: SizeType.ArgArr): <E>(array: readonly E[]) => Optional<E>;
978
- };
977
+ }
979
978
 
980
979
  /**
981
980
  * Returns the first element of an array wrapped in an Optional.
@@ -1048,35 +1047,20 @@ export namespace Arr {
1048
1047
  * @see {@link at} for accessing elements at specific indices
1049
1048
  * @see {@link tail} for getting all elements except the first
1050
1049
  */
1051
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1052
- export const head: HeadFnOverload = (<E,>(array: readonly E[]) => {
1050
+ export function head(array: readonly []): Optional.None;
1051
+
1052
+ export function head<E, L extends readonly unknown[]>(
1053
+ array: readonly [E, ...L],
1054
+ ): Optional.Some<E>;
1055
+
1056
+ export function head<E>(array: NonEmptyArray<E>): Optional.Some<E>;
1057
+
1058
+ export function head<E>(array: readonly E[]): Optional<E>;
1059
+
1060
+ export function head<E>(array: readonly E[]): Optional<E> {
1053
1061
  const element = array.at(0);
1054
1062
  return element === undefined ? Optional.none : Optional.some(element);
1055
- }) as HeadFnOverload;
1056
-
1057
- type HeadFnOverload = {
1058
- /**
1059
- * Get head of empty array.
1060
- */
1061
- (array: readonly []): Optional.None;
1062
-
1063
- /**
1064
- * Get head of tuple.
1065
- */
1066
- <E, L extends readonly unknown[]>(
1067
- array: readonly [E, ...L],
1068
- ): Optional.Some<E>;
1069
-
1070
- /**
1071
- * Get head of non-empty array.
1072
- */
1073
- <E>(array: NonEmptyArray<E>): Optional.Some<E>;
1074
-
1075
- /**
1076
- * Get head of any array.
1077
- */
1078
- <E>(array: readonly E[]): Optional<E>;
1079
- };
1063
+ }
1080
1064
 
1081
1065
  /**
1082
1066
  * Returns the last element of an array wrapped in an Optional.
@@ -1158,35 +1142,20 @@ export namespace Arr {
1158
1142
  * @see {@link at} for accessing elements at specific indices with negative indexing support
1159
1143
  * @see {@link butLast} for getting all elements except the last
1160
1144
  */
1161
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1162
- export const last: LastFnOverload = (<E,>(array: readonly E[]) => {
1145
+ export function last(array: readonly []): Optional.None;
1146
+
1147
+ export function last<Ar extends readonly unknown[], L>(
1148
+ array: readonly [...Ar, L],
1149
+ ): Optional.Some<L>;
1150
+
1151
+ export function last<E>(array: NonEmptyArray<E>): Optional.Some<E>;
1152
+
1153
+ export function last<E>(array: readonly E[]): Optional<E>;
1154
+
1155
+ export function last<E>(array: readonly E[]): Optional<E> {
1163
1156
  const element = array.at(-1);
1164
1157
  return element === undefined ? Optional.none : Optional.some(element);
1165
- }) as LastFnOverload;
1166
-
1167
- type LastFnOverload = {
1168
- /**
1169
- * Get last of empty array.
1170
- */
1171
- (array: readonly []): Optional.None;
1172
-
1173
- /**
1174
- * Get last of tuple.
1175
- */
1176
- <Ar extends readonly unknown[], L>(
1177
- array: readonly [...Ar, L],
1178
- ): Optional.Some<L>;
1179
-
1180
- /**
1181
- * Get last of non-empty array.
1182
- */
1183
- <E>(array: NonEmptyArray<E>): Optional.Some<E>;
1184
-
1185
- /**
1186
- * Get last of any array.
1187
- */
1188
- <E>(array: readonly E[]): Optional<E>;
1189
- };
1158
+ }
1190
1159
 
1191
1160
  // slicing
1192
1161
 
@@ -1273,12 +1242,22 @@ export namespace Arr {
1273
1242
  * @see {@link skip} for skipping the first N elements
1274
1243
  * @see {@link takeLast} for taking the last N elements
1275
1244
  */
1276
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1277
- export const sliceClamped: SliceClampedFnOverload = (<E,>(
1245
+ export function sliceClamped<E>(
1246
+ array: readonly E[],
1247
+ start: SizeType.ArgArr,
1248
+ end: SizeType.ArgArr,
1249
+ ): readonly E[];
1250
+
1251
+ export function sliceClamped(
1252
+ start: SizeType.ArgArr,
1253
+ end: SizeType.ArgArr,
1254
+ ): <E>(array: readonly E[]) => readonly E[];
1255
+
1256
+ export function sliceClamped<E>(
1278
1257
  ...args:
1279
1258
  | readonly [readonly E[], SizeType.ArgArr, SizeType.ArgArr]
1280
1259
  | readonly [SizeType.ArgArr, SizeType.ArgArr]
1281
- ) => {
1260
+ ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
1282
1261
  switch (args.length) {
1283
1262
  case 3: {
1284
1263
  const [array, start, end] = args;
@@ -1289,24 +1268,10 @@ export namespace Arr {
1289
1268
  }
1290
1269
  case 2: {
1291
1270
  const [start, end] = args;
1292
- return <E2,>(array: readonly E2[]) => sliceClamped(array, start, end);
1271
+ return (array) => sliceClamped(array, start, end);
1293
1272
  }
1294
1273
  }
1295
- }) as SliceClampedFnOverload;
1296
-
1297
- type SliceClampedFnOverload = {
1298
- <E>(
1299
- array: readonly E[],
1300
- start: SizeType.ArgArr,
1301
- end: SizeType.ArgArr,
1302
- ): readonly E[];
1303
-
1304
- // Curried version
1305
- (
1306
- start: SizeType.ArgArr,
1307
- end: SizeType.ArgArr,
1308
- ): <E>(array: readonly E[]) => readonly E[];
1309
- };
1274
+ }
1310
1275
 
1311
1276
  /**
1312
1277
  * Returns all elements of an array except the first one.
@@ -1367,12 +1332,41 @@ export namespace Arr {
1367
1332
  * console.log(result); // [1, 2, 3]
1368
1333
  * ```
1369
1334
  */
1370
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1371
- export const take: TakeFnOverload = (<Ar extends readonly unknown[]>(
1335
+ export function take<Ar extends readonly unknown[], N extends SmallUint>(
1336
+ array: Ar,
1337
+ num: N,
1338
+ ): List.Take<N, Ar>;
1339
+
1340
+ export function take<N extends SmallUint>(
1341
+ num: N,
1342
+ ): <Ar extends readonly unknown[]>(array: Ar) => List.Take<N, Ar>;
1343
+
1344
+ export function take<E>(
1345
+ array: NonEmptyArray<E>,
1346
+ num: SizeType.ArgArrPositive,
1347
+ ): NonEmptyArray<E>;
1348
+
1349
+ export function take(
1350
+ num: SizeType.ArgArrPositive,
1351
+ ): <E>(array: NonEmptyArray<E>) => NonEmptyArray<E>;
1352
+
1353
+ export function take<E>(
1354
+ array: readonly E[],
1355
+ num: SizeType.ArgArrNonNegative,
1356
+ ): readonly E[];
1357
+
1358
+ export function take(
1359
+ num: SizeType.ArgArrNonNegative,
1360
+ ): <E>(array: readonly E[]) => readonly E[];
1361
+
1362
+ export function take<E>(
1372
1363
  ...args:
1373
- | readonly [array: Ar, num: SizeType.ArgArrNonNegative]
1364
+ | readonly [array: readonly E[], num: SizeType.ArgArrNonNegative]
1374
1365
  | readonly [num: SizeType.ArgArrNonNegative]
1375
- ) => {
1366
+ ):
1367
+ | readonly E[]
1368
+ | ((array: NonEmptyArray<E>) => NonEmptyArray<E>)
1369
+ | ((array: readonly E[]) => readonly E[]) {
1376
1370
  switch (args.length) {
1377
1371
  case 2: {
1378
1372
  const [array, num] = args;
@@ -1380,37 +1374,10 @@ export namespace Arr {
1380
1374
  }
1381
1375
  case 1: {
1382
1376
  const [num] = args;
1383
- return <E,>(array: readonly E[]) => take(array, num);
1377
+ return (array: readonly E[]) => take(array, num);
1384
1378
  }
1385
1379
  }
1386
- }) as unknown as TakeFnOverload;
1387
-
1388
- type TakeFnOverload = {
1389
- <Ar extends readonly unknown[], N extends SmallUint>(
1390
- array: Ar,
1391
- num: N,
1392
- ): List.Take<N, Ar>;
1393
-
1394
- // curried version
1395
- <N extends SmallUint>(
1396
- num: N,
1397
- ): <Ar extends readonly unknown[]>(array: Ar) => List.Take<N, Ar>;
1398
-
1399
- <E>(
1400
- array: NonEmptyArray<E>,
1401
- num: SizeType.ArgArrPositive,
1402
- ): NonEmptyArray<E>;
1403
-
1404
- // curried version
1405
- (
1406
- num: SizeType.ArgArrPositive,
1407
- ): <E>(array: NonEmptyArray<E>) => NonEmptyArray<E>;
1408
-
1409
- <E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1410
-
1411
- // curried version
1412
- (num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1413
- };
1380
+ }
1414
1381
 
1415
1382
  /**
1416
1383
  * Takes the last N elements from an array.
@@ -1435,12 +1402,41 @@ export namespace Arr {
1435
1402
  * console.log(result); // [4, 5]
1436
1403
  * ```
1437
1404
  */
1438
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1439
- export const takeLast: TakeLastFnOverload = (<Ar extends readonly unknown[]>(
1405
+ export function takeLast<Ar extends readonly unknown[], N extends SmallUint>(
1406
+ array: Ar,
1407
+ num: N,
1408
+ ): List.TakeLast<N, Ar>;
1409
+
1410
+ export function takeLast<N extends SmallUint>(
1411
+ num: N,
1412
+ ): <Ar extends readonly unknown[]>(array: Ar) => List.TakeLast<N, Ar>;
1413
+
1414
+ export function takeLast<E>(
1415
+ array: NonEmptyArray<E>,
1416
+ num: SizeType.ArgArrPositive,
1417
+ ): NonEmptyArray<E>;
1418
+
1419
+ export function takeLast(
1420
+ num: SizeType.ArgArrPositive,
1421
+ ): <E>(array: NonEmptyArray<E>) => NonEmptyArray<E>;
1422
+
1423
+ export function takeLast<E>(
1424
+ array: readonly E[],
1425
+ num: SizeType.ArgArrNonNegative,
1426
+ ): readonly E[];
1427
+
1428
+ export function takeLast(
1429
+ num: SizeType.ArgArrNonNegative,
1430
+ ): <E>(array: readonly E[]) => readonly E[];
1431
+
1432
+ export function takeLast<E>(
1440
1433
  ...args:
1441
- | readonly [array: Ar, num: SizeType.ArgArrNonNegative]
1434
+ | readonly [array: readonly E[], num: SizeType.ArgArrNonNegative]
1442
1435
  | readonly [num: SizeType.ArgArrNonNegative]
1443
- ) => {
1436
+ ):
1437
+ | readonly E[]
1438
+ | ((array: NonEmptyArray<E>) => NonEmptyArray<E>)
1439
+ | ((array: readonly E[]) => readonly E[]) {
1444
1440
  switch (args.length) {
1445
1441
  case 2: {
1446
1442
  const [array, num] = args;
@@ -1448,37 +1444,10 @@ export namespace Arr {
1448
1444
  }
1449
1445
  case 1: {
1450
1446
  const [num] = args;
1451
- return <E,>(array: readonly E[]) => takeLast(array, num);
1447
+ return (array: readonly E[]) => takeLast(array, num);
1452
1448
  }
1453
1449
  }
1454
- }) as unknown as TakeLastFnOverload;
1455
-
1456
- type TakeLastFnOverload = {
1457
- <Ar extends readonly unknown[], N extends SmallUint>(
1458
- array: Ar,
1459
- num: N,
1460
- ): List.TakeLast<N, Ar>;
1461
-
1462
- // curried version
1463
- <N extends SmallUint>(
1464
- num: N,
1465
- ): <Ar extends readonly unknown[]>(array: Ar) => List.TakeLast<N, Ar>;
1466
-
1467
- <E>(
1468
- array: NonEmptyArray<E>,
1469
- num: SizeType.ArgArrPositive,
1470
- ): NonEmptyArray<E>;
1471
-
1472
- // curried version
1473
- (
1474
- num: SizeType.ArgArrPositive,
1475
- ): <E>(array: NonEmptyArray<E>) => NonEmptyArray<E>;
1476
-
1477
- <E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1478
-
1479
- // curried version
1480
- (num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1481
- };
1450
+ }
1482
1451
 
1483
1452
  /**
1484
1453
  * Skips the first N elements of an array.
@@ -1503,12 +1472,41 @@ export namespace Arr {
1503
1472
  * console.log(result); // [3, 4, 5]
1504
1473
  * ```
1505
1474
  */
1506
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1507
- export const skip: SkipFnOverload = (<E,>(
1475
+ export function skip<Ar extends readonly unknown[], N extends SmallUint>(
1476
+ array: Ar,
1477
+ num: N,
1478
+ ): List.Skip<N, Ar>;
1479
+
1480
+ export function skip<E>(
1481
+ array: NonEmptyArray<E>,
1482
+ num: SizeType.ArgArrPositive,
1483
+ ): readonly E[];
1484
+
1485
+ export function skip<E>(
1486
+ array: readonly E[],
1487
+ num: SizeType.ArgArrNonNegative,
1488
+ ): readonly E[];
1489
+
1490
+ export function skip<N extends SmallUint>(
1491
+ num: N,
1492
+ ): <Ar extends readonly unknown[]>(array: Ar) => List.Skip<N, Ar>;
1493
+
1494
+ export function skip(
1495
+ num: SizeType.ArgArrPositive,
1496
+ ): <E>(array: NonEmptyArray<E>) => readonly E[];
1497
+
1498
+ export function skip(
1499
+ num: SizeType.ArgArrNonNegative,
1500
+ ): <E>(array: readonly E[]) => readonly E[];
1501
+
1502
+ export function skip<E>(
1508
1503
  ...args:
1509
1504
  | readonly [readonly E[], SizeType.ArgArrNonNegative]
1510
1505
  | readonly [SizeType.ArgArrNonNegative]
1511
- ) => {
1506
+ ):
1507
+ | readonly E[]
1508
+ | ((array: NonEmptyArray<E>) => readonly E[])
1509
+ | ((array: readonly E[]) => readonly E[]) {
1512
1510
  switch (args.length) {
1513
1511
  case 2: {
1514
1512
  const [array, num] = args;
@@ -1516,32 +1514,10 @@ export namespace Arr {
1516
1514
  }
1517
1515
  case 1: {
1518
1516
  const [num] = args;
1519
- return <E2,>(array: readonly E2[]) => skip(array, num);
1517
+ return (array: readonly E[]) => skip(array, num);
1520
1518
  }
1521
1519
  }
1522
- }) as SkipFnOverload;
1523
-
1524
- type SkipFnOverload = {
1525
- <Ar extends readonly unknown[], N extends SmallUint>(
1526
- array: Ar,
1527
- num: N,
1528
- ): List.Skip<N, Ar>;
1529
-
1530
- <E>(array: NonEmptyArray<E>, num: SizeType.ArgArrPositive): readonly E[];
1531
-
1532
- <E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1533
-
1534
- // curried version
1535
- <N extends SmallUint>(
1536
- num: N,
1537
- ): <Ar extends readonly unknown[]>(array: Ar) => List.Skip<N, Ar>;
1538
-
1539
- (
1540
- num: SizeType.ArgArrPositive,
1541
- ): <E>(array: NonEmptyArray<E>) => readonly E[];
1542
-
1543
- (num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1544
- };
1520
+ }
1545
1521
 
1546
1522
  /**
1547
1523
  * Skips the last N elements of an array.
@@ -1566,12 +1542,29 @@ export namespace Arr {
1566
1542
  * console.log(result); // [1, 2, 3]
1567
1543
  * ```
1568
1544
  */
1569
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1570
- export const skipLast: SkipLastFnOverload = (<E,>(
1545
+ export function skipLast<Ar extends readonly unknown[], N extends SmallUint>(
1546
+ array: Ar,
1547
+ num: N,
1548
+ ): List.SkipLast<N, Ar>;
1549
+
1550
+ export function skipLast<N extends SmallUint>(
1551
+ num: N,
1552
+ ): <Ar extends readonly unknown[]>(array: Ar) => List.SkipLast<N, Ar>;
1553
+
1554
+ export function skipLast<E>(
1555
+ array: readonly E[],
1556
+ num: SizeType.ArgArrNonNegative,
1557
+ ): readonly E[];
1558
+
1559
+ export function skipLast(
1560
+ num: SizeType.ArgArrNonNegative,
1561
+ ): <E>(array: readonly E[]) => readonly E[];
1562
+
1563
+ export function skipLast<E>(
1571
1564
  ...args:
1572
1565
  | readonly [array: readonly E[], num: SizeType.ArgArrNonNegative]
1573
1566
  | readonly [num: SizeType.ArgArrNonNegative]
1574
- ): readonly E[] | ((array: readonly E[]) => readonly E[]) => {
1567
+ ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
1575
1568
  switch (args.length) {
1576
1569
  case 2: {
1577
1570
  const [array, num] = args;
@@ -1579,26 +1572,10 @@ export namespace Arr {
1579
1572
  }
1580
1573
  case 1: {
1581
1574
  const [num] = args;
1582
- return <E2,>(array: readonly E2[]) => skipLast(array, num);
1575
+ return (array: readonly E[]) => skipLast(array, num);
1583
1576
  }
1584
1577
  }
1585
- }) as SkipLastFnOverload;
1586
-
1587
- type SkipLastFnOverload = {
1588
- <Ar extends readonly unknown[], N extends SmallUint>(
1589
- array: Ar,
1590
- num: N,
1591
- ): List.SkipLast<N, Ar>;
1592
-
1593
- <E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1594
-
1595
- // curried version
1596
- <N extends SmallUint>(
1597
- num: N,
1598
- ): <Ar extends readonly unknown[]>(array: Ar) => List.SkipLast<N, Ar>;
1599
-
1600
- (num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1601
- };
1578
+ }
1602
1579
 
1603
1580
  // modification (returns new array)
1604
1581
 
@@ -1756,8 +1733,18 @@ export namespace Arr {
1756
1733
  * @see {@link SizeType.ArgArrNonNegative} for the index type constraint
1757
1734
  * @see Immutable update patterns for functional programming approaches
1758
1735
  */
1759
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1760
- export const toUpdated: ToUpdatedFnOverload = (<E, U>(
1736
+ export function toUpdated<E, U>(
1737
+ array: readonly E[],
1738
+ index: SizeType.ArgArrNonNegative,
1739
+ updater: (prev: E) => U,
1740
+ ): readonly (E | U)[];
1741
+
1742
+ export function toUpdated<E, U>(
1743
+ index: SizeType.ArgArrNonNegative,
1744
+ updater: (prev: E) => U,
1745
+ ): (array: readonly E[]) => readonly (E | U)[];
1746
+
1747
+ export function toUpdated<E, U>(
1761
1748
  ...args:
1762
1749
  | readonly [
1763
1750
  array: readonly E[],
@@ -1765,7 +1752,7 @@ export namespace Arr {
1765
1752
  updater: (prev: E) => U,
1766
1753
  ]
1767
1754
  | readonly [index: SizeType.ArgArrNonNegative, updater: (prev: E) => U]
1768
- ) => {
1755
+ ): readonly (E | U)[] | ((array: readonly E[]) => readonly (E | U)[]) {
1769
1756
  switch (args.length) {
1770
1757
  case 3: {
1771
1758
  const [array, index, updater] = args;
@@ -1779,21 +1766,7 @@ export namespace Arr {
1779
1766
  return (array: readonly E[]) => toUpdated(array, index, updater);
1780
1767
  }
1781
1768
  }
1782
- }) as ToUpdatedFnOverload;
1783
-
1784
- type ToUpdatedFnOverload = {
1785
- <E, U>(
1786
- array: readonly E[],
1787
- index: SizeType.ArgArrNonNegative,
1788
- updater: (prev: E) => U,
1789
- ): readonly (E | U)[];
1790
-
1791
- // curried version
1792
- <E, U>(
1793
- index: SizeType.ArgArrNonNegative,
1794
- updater: (prev: E) => U,
1795
- ): (array: readonly E[]) => readonly (E | U)[];
1796
- };
1769
+ }
1797
1770
 
1798
1771
  /**
1799
1772
  * Returns a new array with a new value inserted at the specified index.
@@ -1814,8 +1787,18 @@ export namespace Arr {
1814
1787
  * console.log(result); // [99, 1, 2, 3]
1815
1788
  * ```
1816
1789
  */
1817
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1818
- export const toInserted: ToInsertedFnOverload = (<E, V = E>(
1790
+ export function toInserted<E, const V = E>(
1791
+ array: readonly E[],
1792
+ index: SizeType.ArgArrNonNegative,
1793
+ newValue: V,
1794
+ ): NonEmptyArray<E | V>;
1795
+
1796
+ export function toInserted<E, const V = E>(
1797
+ index: SizeType.ArgArrNonNegative,
1798
+ newValue: V,
1799
+ ): (array: readonly E[]) => NonEmptyArray<E | V>;
1800
+
1801
+ export function toInserted<E, const V = E>(
1819
1802
  ...args:
1820
1803
  | readonly [
1821
1804
  array: readonly E[],
@@ -1823,38 +1806,23 @@ export namespace Arr {
1823
1806
  newValue: V,
1824
1807
  ]
1825
1808
  | readonly [index: SizeType.ArgArrNonNegative, newValue: V]
1826
- ) => {
1809
+ ): NonEmptyArray<E | V> | ((array: readonly E[]) => NonEmptyArray<E | V>) {
1827
1810
  switch (args.length) {
1828
1811
  case 3: {
1829
1812
  const [array, index, newValue] = args;
1830
1813
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1831
- return (array as (E | V)[]).toSpliced(
1814
+ return (array as readonly (E | V)[]).toSpliced(
1832
1815
  index,
1833
1816
  0,
1834
1817
  newValue,
1835
- ) as MutableNonEmptyArray<E | V>;
1818
+ ) as unknown as NonEmptyArray<E | V>;
1836
1819
  }
1837
1820
  case 2: {
1838
1821
  const [index, newValue] = args;
1839
- return <E2,>(array: readonly (E2 | V)[]) =>
1840
- toInserted(array, index, newValue);
1822
+ return (array: readonly E[]) => toInserted(array, index, newValue);
1841
1823
  }
1842
1824
  }
1843
- }) as ToInsertedFnOverload;
1844
-
1845
- type ToInsertedFnOverload = {
1846
- <E, const V = E>(
1847
- array: readonly E[],
1848
- index: SizeType.ArgArrNonNegative,
1849
- newValue: V,
1850
- ): NonEmptyArray<E | V>;
1851
-
1852
- // curried version
1853
- <E, const V = E>(
1854
- index: SizeType.ArgArrNonNegative,
1855
- newValue: V,
1856
- ): (array: readonly E[]) => NonEmptyArray<E | V>;
1857
- };
1825
+ }
1858
1826
 
1859
1827
  /**
1860
1828
  * Returns a new array with the element at the specified index removed.
@@ -1874,12 +1842,20 @@ export namespace Arr {
1874
1842
  * console.log(result); // [20, 30]
1875
1843
  * ```
1876
1844
  */
1877
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1878
- export const toRemoved: ToRemovedFnOverload = (<E,>(
1845
+ export function toRemoved<E>(
1846
+ array: readonly E[],
1847
+ index: SizeType.ArgArrNonNegative,
1848
+ ): readonly E[];
1849
+
1850
+ export function toRemoved(
1851
+ index: SizeType.ArgArrNonNegative,
1852
+ ): <E>(array: readonly E[]) => readonly E[];
1853
+
1854
+ export function toRemoved<E>(
1879
1855
  ...args:
1880
1856
  | readonly [array: readonly E[], index: SizeType.ArgArrNonNegative]
1881
1857
  | readonly [index: SizeType.ArgArrNonNegative]
1882
- ) => {
1858
+ ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
1883
1859
  switch (args.length) {
1884
1860
  case 2: {
1885
1861
  const [array, index] = args;
@@ -1887,19 +1863,10 @@ export namespace Arr {
1887
1863
  }
1888
1864
  case 1: {
1889
1865
  const [index] = args;
1890
- return <E2,>(array: readonly E2[]) => toRemoved(array, index);
1866
+ return (array: readonly E[]) => toRemoved(array, index);
1891
1867
  }
1892
1868
  }
1893
- }) as ToRemovedFnOverload;
1894
-
1895
- type ToRemovedFnOverload = {
1896
- <E>(array: readonly E[], index: SizeType.ArgArrNonNegative): readonly E[];
1897
-
1898
- // curried version
1899
- (
1900
- index: SizeType.ArgArrNonNegative,
1901
- ): <E>(array: readonly E[]) => readonly E[];
1902
- };
1869
+ }
1903
1870
 
1904
1871
  /**
1905
1872
  * Returns a new array with a value added to the end.
@@ -1919,37 +1886,34 @@ export namespace Arr {
1919
1886
  * console.log(result); // [1, 2, 3, 0]
1920
1887
  * ```
1921
1888
  */
1922
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1923
- export const toPushed: ToPushedFnOverload = (<
1924
- Ar extends readonly unknown[],
1925
- const V,
1926
- >(
1889
+ export function toPushed<Ar extends readonly unknown[], const V>(
1890
+ array: Ar,
1891
+ newValue: V,
1892
+ ): readonly [...Ar, V];
1893
+
1894
+ export function toPushed<const V>(
1895
+ newValue: V,
1896
+ ): <Ar extends readonly unknown[]>(array: Ar) => readonly [...Ar, V];
1897
+
1898
+ export function toPushed<Ar extends readonly unknown[], const V>(
1927
1899
  ...args: readonly [array: Ar, newValue: V] | readonly [newValue: V]
1928
- ) => {
1900
+ ): readonly [...Ar, V] | ((array: Ar) => readonly [...Ar, V]) {
1929
1901
  switch (args.length) {
1930
1902
  case 2: {
1931
1903
  const [array, newValue] = args;
1932
- return array.toSpliced(array.length, 0, newValue);
1904
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1905
+ return array.toSpliced(
1906
+ array.length,
1907
+ 0,
1908
+ newValue,
1909
+ ) as unknown as readonly [...Ar, V];
1933
1910
  }
1934
1911
  case 1: {
1935
1912
  const [newValue] = args;
1936
- return <Ar2 extends readonly unknown[]>(array: Ar2) =>
1937
- toPushed(array, newValue);
1913
+ return (array) => toPushed(array, newValue);
1938
1914
  }
1939
1915
  }
1940
- }) as unknown as ToPushedFnOverload;
1941
-
1942
- type ToPushedFnOverload = {
1943
- <Ar extends readonly unknown[], const V>(
1944
- array: Ar,
1945
- newValue: V,
1946
- ): readonly [...Ar, V];
1947
-
1948
- // curried version
1949
- <const V>(
1950
- newValue: V,
1951
- ): <Ar extends readonly unknown[]>(array: Ar) => readonly [...Ar, V];
1952
- };
1916
+ }
1953
1917
 
1954
1918
  /**
1955
1919
  * Returns a new array with a value added to the beginning.
@@ -1969,37 +1933,33 @@ export namespace Arr {
1969
1933
  * console.log(result); // [0, 1, 2, 3]
1970
1934
  * ```
1971
1935
  */
1972
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1973
- export const toUnshifted: ToUnshiftedFnOverload = (<
1974
- Ar extends readonly unknown[],
1975
- const V,
1976
- >(
1936
+ export function toUnshifted<Ar extends readonly unknown[], const V>(
1937
+ array: Ar,
1938
+ newValue: V,
1939
+ ): readonly [V, ...Ar];
1940
+
1941
+ export function toUnshifted<const V>(
1942
+ newValue: V,
1943
+ ): <Ar extends readonly unknown[]>(array: Ar) => readonly [V, ...Ar];
1944
+
1945
+ export function toUnshifted<Ar extends readonly unknown[], const V>(
1977
1946
  ...args: readonly [array: Ar, newValue: V] | readonly [newValue: V]
1978
- ) => {
1947
+ ): readonly [V, ...Ar] | ((array: Ar) => readonly [V, ...Ar]) {
1979
1948
  switch (args.length) {
1980
1949
  case 2: {
1981
1950
  const [array, newValue] = args;
1982
- return array.toSpliced(0, 0, newValue);
1951
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
1952
+ return array.toSpliced(0, 0, newValue) as unknown as readonly [
1953
+ V,
1954
+ ...Ar,
1955
+ ];
1983
1956
  }
1984
1957
  case 1: {
1985
1958
  const [newValue] = args;
1986
- return <Ar2 extends readonly unknown[]>(array: Ar2) =>
1987
- toUnshifted(array, newValue);
1959
+ return (array) => toUnshifted(array, newValue);
1988
1960
  }
1989
1961
  }
1990
- }) as unknown as ToUnshiftedFnOverload;
1991
-
1992
- type ToUnshiftedFnOverload = {
1993
- <Ar extends readonly unknown[], const V>(
1994
- array: Ar,
1995
- newValue: V,
1996
- ): readonly [V, ...Ar];
1997
-
1998
- // curried version
1999
- <const V>(
2000
- newValue: V,
2001
- ): <Ar extends readonly unknown[]>(array: Ar) => readonly [V, ...Ar];
2002
- };
1962
+ }
2003
1963
 
2004
1964
  /**
2005
1965
  * Fills an array with a value (creates a new filled array).
@@ -2021,10 +1981,13 @@ export namespace Arr {
2021
1981
  * console.log(result2); // [1, 0, 0, 4]
2022
1982
  * ```
2023
1983
  */
2024
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2025
- export const toFilled: ToFilledFnOverload = (<E,>(
1984
+ export function toFilled<E>(array: readonly E[], value: E): readonly E[];
1985
+
1986
+ export function toFilled<E>(value: E): (array: readonly E[]) => readonly E[];
1987
+
1988
+ export function toFilled<E>(
2026
1989
  ...args: readonly [array: readonly E[], value: E] | readonly [value: E]
2027
- ) => {
1990
+ ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
2028
1991
  switch (args.length) {
2029
1992
  case 2: {
2030
1993
  const [array, value] = args;
@@ -2034,20 +1997,23 @@ export namespace Arr {
2034
1997
  }
2035
1998
  case 1: {
2036
1999
  const [value] = args;
2037
- return (array: readonly E[]) => toFilled(array, value);
2000
+ return (array) => toFilled(array, value);
2038
2001
  }
2039
2002
  }
2040
- }) as ToFilledFnOverload;
2003
+ }
2041
2004
 
2042
- type ToFilledFnOverload = {
2043
- <E>(array: readonly E[], value: E): readonly E[];
2005
+ export function toRangeFilled<E>(
2006
+ array: readonly E[],
2007
+ value: E,
2008
+ fillRange: readonly [start: SizeType.ArgArr, end: SizeType.ArgArr],
2009
+ ): readonly E[];
2044
2010
 
2045
- // curried version
2046
- <E>(value: E): (array: readonly E[]) => readonly E[];
2047
- };
2011
+ export function toRangeFilled<E>(
2012
+ value: E,
2013
+ fillRange: readonly [start: SizeType.ArgArr, end: SizeType.ArgArr],
2014
+ ): (array: readonly E[]) => readonly E[];
2048
2015
 
2049
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2050
- export const toRangeFilled: ToRangeFilledFnOverload = (<E,>(
2016
+ export function toRangeFilled<E>(
2051
2017
  ...args:
2052
2018
  | readonly [
2053
2019
  array: readonly E[],
@@ -2058,7 +2024,7 @@ export namespace Arr {
2058
2024
  value: E,
2059
2025
  fillRange: readonly [start: SizeType.ArgArr, end: SizeType.ArgArr],
2060
2026
  ]
2061
- ) => {
2027
+ ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
2062
2028
  switch (args.length) {
2063
2029
  case 3: {
2064
2030
  const [array, value, [start, end]] = args;
@@ -2068,25 +2034,10 @@ export namespace Arr {
2068
2034
  }
2069
2035
  case 2: {
2070
2036
  const [value, fillRange] = args;
2071
- return (array: readonly unknown[]) =>
2072
- toRangeFilled(array, value, fillRange);
2037
+ return (array) => toRangeFilled(array, value, fillRange);
2073
2038
  }
2074
2039
  }
2075
- }) as ToRangeFilledFnOverload;
2076
-
2077
- type ToRangeFilledFnOverload = {
2078
- <E>(
2079
- array: readonly E[],
2080
- value: E,
2081
- fillRange: readonly [start: SizeType.ArgArr, end: SizeType.ArgArr],
2082
- ): readonly E[];
2083
-
2084
- // curried version
2085
- <E>(
2086
- value: E,
2087
- fillRange: readonly [start: SizeType.ArgArr, end: SizeType.ArgArr],
2088
- ): (array: readonly E[]) => readonly E[];
2089
- };
2040
+ }
2090
2041
 
2091
2042
  // searching
2092
2043
 
@@ -2112,80 +2063,31 @@ export namespace Arr {
2112
2063
  *
2113
2064
  * @example
2114
2065
  * ```typescript
2115
- * // Basic element finding
2116
2066
  * const numbers = [1, 2, 3, 4, 5];
2117
2067
  * const firstEven = Arr.find(numbers, x => x % 2 === 0);
2118
2068
  * if (Optional.isSome(firstEven)) {
2119
- * console.log(firstEven.value); // 2 - first even number
2069
+ * console.log(firstEven.value); // 2
2120
2070
  * }
2121
2071
  *
2122
- * // Finding with index information
2123
- * const findLargeAtEnd = Arr.find(numbers, (value, index) => value > 3 && index > 2);
2124
- * // Optional.Some(4) - first number > 3 after index 2
2125
- *
2126
- * // Finding objects by property
2127
- * const users = [
2128
- * { id: 1, name: 'Alice', age: 25 },
2129
- * { id: 2, name: 'Bob', age: 30 },
2130
- * { id: 3, name: 'Charlie', age: 35 }
2131
- * ];
2132
- *
2072
+ * const users = [{ id: 1, name: 'Alice', age: 25 }, { id: 2, name: 'Bob', age: 30 }];
2133
2073
  * const adult = Arr.find(users, user => user.age >= 30);
2134
2074
  * // Optional.Some({ id: 2, name: 'Bob', age: 30 })
2135
- *
2136
- * const nonExistent = Arr.find(users, user => user.age > 100);
2137
- * // Optional.None
2138
- *
2139
- * // Empty array handling
2140
- * const emptyResult = Arr.find([], x => x > 0); // Optional.None
2141
- *
2142
- * // Curried usage for functional composition
2143
- * const findNegative = Arr.find((x: number) => x < 0);
2144
- * const findLongString = Arr.find((s: string) => s.length > 5);
2145
- *
2146
- * const datasets = [
2147
- * [1, 2, -3, 4],
2148
- * [5, 6, 7, 8],
2149
- * [-1, 0, 1]
2150
- * ];
2151
- *
2152
- * const negativeNumbers = datasets.map(findNegative);
2153
- * // [Optional.Some(-3), Optional.None, Optional.Some(-1)]
2154
- *
2155
- * // Pipe composition
2156
- * const result = pipe(['short', 'medium', 'very long string'])
2157
- * .map(findLongString)
2158
- * .map(opt => Optional.unwrapOr(opt, 'default'))
2159
- * .value; // 'very long string'
2160
- *
2161
- * // Complex predicate with all parameters
2162
- * const findSpecial = (arr: readonly number[]) =>
2163
- * Arr.find(arr, (value, index, array) => {
2164
- * return value > 10 && index > 0 && index < array.length - 1;
2165
- * });
2166
- *
2167
- * const hasMiddleSpecial = findSpecial([5, 15, 20, 3]);
2168
- * // Optional.Some(15) - first value > 10 that's not at start or end
2169
- *
2170
- * // Safe unwrapping patterns
2171
- * const maybeFound = Arr.find(numbers, x => x > 10);
2172
- * const foundOrDefault = Optional.unwrapOr(maybeFound, 0); // 0 (not found)
2173
- * const foundOrThrow = Optional.isSome(maybeFound)
2174
- * ? maybeFound.value
2175
- * : (() => { throw new Error('Not found'); })();
2176
- *
2177
- * // Type inference examples
2178
- * expectType<typeof firstEven, Optional<number>>('=');
2179
- * expectType<typeof adult, Optional<{id: number, name: string, age: number}>>('=');
2180
- * expectType<typeof findNegative, (array: readonly number[]) => Optional<number>>('=');
2181
2075
  * ```
2182
2076
  *
2183
2077
  * @see {@link findIndex} for finding the index instead of the element
2184
2078
  * @see {@link indexOf} for finding elements by equality
2185
2079
  * @see {@link Optional} for working with the returned Optional values
2186
2080
  */
2187
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2188
- export const find: FindFnOverload = (<E,>(
2081
+ export function find<E>(
2082
+ array: readonly E[],
2083
+ predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
2084
+ ): Optional<E>;
2085
+
2086
+ export function find<E>(
2087
+ predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
2088
+ ): (array: readonly E[]) => Optional<E>;
2089
+
2090
+ export function find<E>(
2189
2091
  ...args:
2190
2092
  | readonly [
2191
2093
  array: readonly E[],
@@ -2202,7 +2104,7 @@ export namespace Arr {
2202
2104
  arr: readonly E[],
2203
2105
  ) => boolean,
2204
2106
  ]
2205
- ) => {
2107
+ ): Optional<E> | ((array: readonly E[]) => Optional<E>) {
2206
2108
  switch (args.length) {
2207
2109
  case 2: {
2208
2110
  const [array, predicate] = args;
@@ -2221,19 +2123,7 @@ export namespace Arr {
2221
2123
  return (array: readonly E[]) => find(array, predicate);
2222
2124
  }
2223
2125
  }
2224
- }) as FindFnOverload;
2225
-
2226
- type FindFnOverload = {
2227
- <E>(
2228
- array: readonly E[],
2229
- predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
2230
- ): Optional<E>;
2231
-
2232
- // curried version
2233
- <E>(
2234
- predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean,
2235
- ): (array: readonly E[]) => Optional<E>;
2236
- };
2126
+ }
2237
2127
 
2238
2128
  /**
2239
2129
  * Safely finds the index of the first element in an array that satisfies a predicate function.
@@ -2340,15 +2230,23 @@ export namespace Arr {
2340
2230
  * @see {@link lastIndexOf} for finding the last occurrence
2341
2231
  * @see {@link Optional} for working with the returned Optional values
2342
2232
  */
2343
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2344
- export const findIndex: FindIndexFnOverload = (<E,>(
2233
+ export function findIndex<E>(
2234
+ array: readonly E[],
2235
+ predicate: (value: E, index: SizeType.Arr) => boolean,
2236
+ ): SizeType.Arr | -1;
2237
+
2238
+ export function findIndex<E>(
2239
+ predicate: (value: E, index: SizeType.Arr) => boolean,
2240
+ ): (array: readonly E[]) => SizeType.Arr | -1;
2241
+
2242
+ export function findIndex<E>(
2345
2243
  ...args:
2346
2244
  | readonly [
2347
2245
  array: readonly E[],
2348
2246
  predicate: (value: E, index: SizeType.Arr) => boolean,
2349
2247
  ]
2350
2248
  | readonly [predicate: (value: E, index: SizeType.Arr) => boolean]
2351
- ) => {
2249
+ ): SizeType.Arr | -1 | ((array: readonly E[]) => SizeType.Arr | -1) {
2352
2250
  switch (args.length) {
2353
2251
  case 2: {
2354
2252
  const [array, predicate] = args;
@@ -2364,19 +2262,7 @@ export namespace Arr {
2364
2262
  return (array: readonly E[]) => findIndex(array, predicate);
2365
2263
  }
2366
2264
  }
2367
- }) as FindIndexFnOverload;
2368
-
2369
- type FindIndexFnOverload = {
2370
- <E>(
2371
- array: readonly E[],
2372
- predicate: (value: E, index: SizeType.Arr) => boolean,
2373
- ): SizeType.Arr | -1;
2374
-
2375
- // curried version
2376
- <E>(
2377
- predicate: (value: E, index: SizeType.Arr) => boolean,
2378
- ): (array: readonly E[]) => SizeType.Arr | -1;
2379
- };
2265
+ }
2380
2266
 
2381
2267
  /**
2382
2268
  * Gets the index of a value in an array.
@@ -2399,12 +2285,20 @@ export namespace Arr {
2399
2285
  * console.log(Optional.unwrapOr(result2, -1)); // 1
2400
2286
  * ```
2401
2287
  */
2402
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2403
- export const indexOf: IndexOfFnOverload = (<E,>(
2288
+ export function indexOf<E>(
2289
+ array: readonly E[],
2290
+ searchElement: E,
2291
+ ): SizeType.Arr | -1;
2292
+
2293
+ export function indexOf<E>(
2294
+ searchElement: E,
2295
+ ): (array: readonly E[]) => SizeType.Arr | -1;
2296
+
2297
+ export function indexOf<E>(
2404
2298
  ...args:
2405
2299
  | readonly [array: readonly E[], searchElement: E]
2406
2300
  | readonly [searchElement: E]
2407
- ) => {
2301
+ ): SizeType.Arr | -1 | ((array: readonly E[]) => SizeType.Arr | -1) {
2408
2302
  switch (args.length) {
2409
2303
  case 2: {
2410
2304
  const [array, searchElement] = args;
@@ -2417,17 +2311,20 @@ export namespace Arr {
2417
2311
  return (array: readonly E[]) => indexOf(array, searchElement);
2418
2312
  }
2419
2313
  }
2420
- }) as IndexOfFnOverload;
2314
+ }
2421
2315
 
2422
- type IndexOfFnOverload = {
2423
- <E>(array: readonly E[], searchElement: E): SizeType.Arr | -1;
2316
+ export function indexOfFrom<E>(
2317
+ array: readonly E[],
2318
+ searchElement: E,
2319
+ fromIndex: SizeType.ArgArr,
2320
+ ): SizeType.Arr | -1;
2424
2321
 
2425
- // curried version
2426
- <E>(searchElement: E): (array: readonly E[]) => SizeType.Arr | -1;
2427
- };
2322
+ export function indexOfFrom<E>(
2323
+ searchElement: E,
2324
+ fromIndex: SizeType.ArgArr,
2325
+ ): (array: readonly E[]) => SizeType.Arr | -1;
2428
2326
 
2429
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2430
- export const indexOfFrom: IndexOfFromFnOverload = (<E,>(
2327
+ export function indexOfFrom<E>(
2431
2328
  ...args:
2432
2329
  | readonly [
2433
2330
  array: readonly E[],
@@ -2435,7 +2332,7 @@ export namespace Arr {
2435
2332
  fromIndex: SizeType.ArgArr,
2436
2333
  ]
2437
2334
  | readonly [searchElement: E, fromIndex: SizeType.ArgArr]
2438
- ) => {
2335
+ ): SizeType.Arr | -1 | ((array: readonly E[]) => SizeType.Arr | -1) {
2439
2336
  switch (args.length) {
2440
2337
  case 3: {
2441
2338
  const [array, searchElement, fromIndex] = args;
@@ -2448,21 +2345,7 @@ export namespace Arr {
2448
2345
  indexOfFrom(array, searchElement, fromIndex);
2449
2346
  }
2450
2347
  }
2451
- }) as IndexOfFromFnOverload;
2452
-
2453
- type IndexOfFromFnOverload = {
2454
- <E>(
2455
- array: readonly E[],
2456
- searchElement: E,
2457
- fromIndex: SizeType.ArgArr,
2458
- ): SizeType.Arr | -1;
2459
-
2460
- // curried version
2461
- <E>(
2462
- searchElement: E,
2463
- fromIndex: SizeType.ArgArr,
2464
- ): (array: readonly E[]) => SizeType.Arr | -1;
2465
- };
2348
+ }
2466
2349
 
2467
2350
  /**
2468
2351
  * Gets the last index of a value in an array.
@@ -2485,12 +2368,20 @@ export namespace Arr {
2485
2368
  * console.log(Optional.unwrapOr(result2, -1)); // 3
2486
2369
  * ```
2487
2370
  */
2488
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2489
- export const lastIndexOf: LastIndexOfFnOverload = (<E,>(
2371
+ export function lastIndexOf<E>(
2372
+ array: readonly E[],
2373
+ searchElement: E,
2374
+ ): SizeType.Arr | -1;
2375
+
2376
+ export function lastIndexOf<E>(
2377
+ searchElement: E,
2378
+ ): (array: readonly E[]) => SizeType.Arr | -1;
2379
+
2380
+ export function lastIndexOf<E>(
2490
2381
  ...args:
2491
2382
  | readonly [array: readonly E[], searchElement: E]
2492
2383
  | readonly [searchElement: E]
2493
- ) => {
2384
+ ): SizeType.Arr | -1 | ((array: readonly E[]) => SizeType.Arr | -1) {
2494
2385
  switch (args.length) {
2495
2386
  case 2: {
2496
2387
  const [array, searchElement] = args;
@@ -2502,17 +2393,20 @@ export namespace Arr {
2502
2393
  return (array: readonly E[]) => lastIndexOf(array, searchElement);
2503
2394
  }
2504
2395
  }
2505
- }) as LastIndexOfFnOverload;
2396
+ }
2506
2397
 
2507
- type LastIndexOfFnOverload = {
2508
- <E>(array: readonly E[], searchElement: E): SizeType.Arr | -1;
2398
+ export function lastIndexOfFrom<E>(
2399
+ array: readonly E[],
2400
+ searchElement: E,
2401
+ fromIndex: SizeType.ArgArr,
2402
+ ): SizeType.Arr | -1;
2509
2403
 
2510
- // curried version
2511
- <E>(searchElement: E): (array: readonly E[]) => SizeType.Arr | -1;
2512
- };
2404
+ export function lastIndexOfFrom<E>(
2405
+ searchElement: E,
2406
+ fromIndex: SizeType.ArgArr,
2407
+ ): (array: readonly E[]) => SizeType.Arr | -1;
2513
2408
 
2514
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2515
- export const lastIndexOfFrom: LastIndexOfFromFnOverload = (<E,>(
2409
+ export function lastIndexOfFrom<E>(
2516
2410
  ...args:
2517
2411
  | readonly [
2518
2412
  array: readonly E[],
@@ -2520,7 +2414,7 @@ export namespace Arr {
2520
2414
  fromIndex: SizeType.ArgArr,
2521
2415
  ]
2522
2416
  | readonly [searchElement: E, fromIndex: SizeType.ArgArr]
2523
- ) => {
2417
+ ): SizeType.Arr | -1 | ((array: readonly E[]) => SizeType.Arr | -1) {
2524
2418
  switch (args.length) {
2525
2419
  case 3: {
2526
2420
  const [array, searchElement, fromIndex] = args;
@@ -2535,21 +2429,7 @@ export namespace Arr {
2535
2429
  lastIndexOfFrom(array, searchElement, fromIndex);
2536
2430
  }
2537
2431
  }
2538
- }) as LastIndexOfFromFnOverload;
2539
-
2540
- type LastIndexOfFromFnOverload = {
2541
- <E>(
2542
- array: readonly E[],
2543
- searchElement: E,
2544
- fromIndex: SizeType.ArgArr,
2545
- ): SizeType.Arr | -1;
2546
-
2547
- // curried version
2548
- <E>(
2549
- searchElement: E,
2550
- fromIndex: SizeType.ArgArr,
2551
- ): (array: readonly E[]) => SizeType.Arr | -1;
2552
- };
2432
+ }
2553
2433
 
2554
2434
  // reducing value
2555
2435
 
@@ -2564,16 +2444,30 @@ export namespace Arr {
2564
2444
  * @returns The single value that results from the reduction.
2565
2445
  * @example
2566
2446
  * ```ts
2567
- * // Regular usage
2568
2447
  * Arr.foldl([1, 2, 3], (sum, n) => sum + n, 0); // 6
2569
- *
2570
- * // Curried usage for pipe composition
2571
- * const sumWithZero = Arr.foldl((sum: number, n: number) => sum + n, 0);
2572
- * const result = pipe([1, 2, 3, 4]).map(sumWithZero).value;
2573
- * console.log(result); // 10
2448
+ * Arr.foldl(['a', 'b', 'c'], (acc, str) => acc + str.toUpperCase(), ''); // 'ABC'
2574
2449
  * ```
2575
2450
  */
2576
- export const foldl: FoldlFnOverload = <E, P>(
2451
+ export function foldl<E, P>(
2452
+ array: readonly E[],
2453
+ callbackfn: (
2454
+ previousValue: P,
2455
+ currentValue: E,
2456
+ currentIndex: SizeType.Arr,
2457
+ ) => P,
2458
+ initialValue: P,
2459
+ ): P;
2460
+
2461
+ export function foldl<E, P>(
2462
+ callbackfn: (
2463
+ previousValue: P,
2464
+ currentValue: E,
2465
+ currentIndex: SizeType.Arr,
2466
+ ) => P,
2467
+ initialValue: P,
2468
+ ): (array: readonly E[]) => P;
2469
+
2470
+ export function foldl<E, P>(
2577
2471
  ...args:
2578
2472
  | readonly [
2579
2473
  array: readonly E[],
@@ -2592,7 +2486,7 @@ export namespace Arr {
2592
2486
  ) => P,
2593
2487
  initialValue: P,
2594
2488
  ]
2595
- ) => {
2489
+ ): P | ((array: readonly E[]) => P) {
2596
2490
  switch (args.length) {
2597
2491
  case 3: {
2598
2492
  const [array, callbackfn, initialValue] = args;
@@ -2606,29 +2500,7 @@ export namespace Arr {
2606
2500
  return (array: readonly E[]) => foldl(array, callbackfn, initialValue);
2607
2501
  }
2608
2502
  }
2609
- };
2610
-
2611
- type FoldlFnOverload = {
2612
- <E, P>(
2613
- array: readonly E[],
2614
- callbackfn: (
2615
- previousValue: P,
2616
- currentValue: E,
2617
- currentIndex: SizeType.Arr,
2618
- ) => P,
2619
- initialValue: P,
2620
- ): P;
2621
-
2622
- // curried version
2623
- <E, P>(
2624
- callbackfn: (
2625
- previousValue: P,
2626
- currentValue: E,
2627
- currentIndex: SizeType.Arr,
2628
- ) => P,
2629
- initialValue: P,
2630
- ): (array: readonly E[]) => P;
2631
- };
2503
+ }
2632
2504
 
2633
2505
  /**
2634
2506
  * Applies a function against an accumulator and each element in the array (from right to left) to reduce it to a single value.
@@ -2650,7 +2522,26 @@ export namespace Arr {
2650
2522
  * console.log(result); // "abc"
2651
2523
  * ```
2652
2524
  */
2653
- export const foldr: FoldrFnOverload = <E, P>(
2525
+ export function foldr<E, P>(
2526
+ array: readonly E[],
2527
+ callbackfn: (
2528
+ previousValue: P,
2529
+ currentValue: E,
2530
+ currentIndex: SizeType.Arr,
2531
+ ) => P,
2532
+ initialValue: P,
2533
+ ): P;
2534
+
2535
+ export function foldr<E, P>(
2536
+ callbackfn: (
2537
+ previousValue: P,
2538
+ currentValue: E,
2539
+ currentIndex: SizeType.Arr,
2540
+ ) => P,
2541
+ initialValue: P,
2542
+ ): (array: readonly E[]) => P;
2543
+
2544
+ export function foldr<E, P>(
2654
2545
  ...args:
2655
2546
  | readonly [
2656
2547
  array: readonly E[],
@@ -2669,7 +2560,7 @@ export namespace Arr {
2669
2560
  ) => P,
2670
2561
  initialValue: P,
2671
2562
  ]
2672
- ) => {
2563
+ ): P | ((array: readonly E[]) => P) {
2673
2564
  switch (args.length) {
2674
2565
  case 3: {
2675
2566
  const [array, callbackfn, initialValue] = args;
@@ -2683,29 +2574,7 @@ export namespace Arr {
2683
2574
  return (array: readonly E[]) => foldr(array, callbackfn, initialValue);
2684
2575
  }
2685
2576
  }
2686
- };
2687
-
2688
- type FoldrFnOverload = {
2689
- <E, P>(
2690
- array: readonly E[],
2691
- callbackfn: (
2692
- previousValue: P,
2693
- currentValue: E,
2694
- currentIndex: SizeType.Arr,
2695
- ) => P,
2696
- initialValue: P,
2697
- ): P;
2698
-
2699
- // curried version
2700
- <E, P>(
2701
- callbackfn: (
2702
- previousValue: P,
2703
- currentValue: E,
2704
- currentIndex: SizeType.Arr,
2705
- ) => P,
2706
- initialValue: P,
2707
- ): (array: readonly E[]) => P;
2708
- };
2577
+ }
2709
2578
 
2710
2579
  /**
2711
2580
  * Finds the minimum value in an array.
@@ -2720,12 +2589,30 @@ export namespace Arr {
2720
2589
  * Arr.min([]); // Optional.none
2721
2590
  * ```
2722
2591
  */
2592
+ export function min<E extends number>(
2593
+ array: NonEmptyArray<E>,
2594
+ comparator?: (x: E, y: E) => number,
2595
+ ): Optional.Some<E>;
2723
2596
 
2724
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2725
- export const min: MinFnOverload = (<E extends number>(
2597
+ export function min<E extends number>(
2726
2598
  array: readonly E[],
2727
2599
  comparator?: (x: E, y: E) => number,
2728
- ): Optional<E> => {
2600
+ ): Optional<E>;
2601
+
2602
+ export function min<E>(
2603
+ array: NonEmptyArray<E>,
2604
+ comparator: (x: E, y: E) => number,
2605
+ ): Optional.Some<E>;
2606
+
2607
+ export function min<E>(
2608
+ array: readonly E[],
2609
+ comparator: (x: E, y: E) => number,
2610
+ ): Optional<E>;
2611
+
2612
+ export function min<E extends number>(
2613
+ array: readonly E[],
2614
+ comparator?: (x: E, y: E) => number,
2615
+ ): Optional<E> {
2729
2616
  if (!isNonEmpty(array)) {
2730
2617
  return Optional.none;
2731
2618
  }
@@ -2738,26 +2625,7 @@ export namespace Arr {
2738
2625
  array[0],
2739
2626
  ),
2740
2627
  );
2741
- }) as MinFnOverload;
2742
-
2743
- type MinFnOverload = {
2744
- <E extends number>(
2745
- array: NonEmptyArray<E>,
2746
- comparator?: (x: E, y: E) => number,
2747
- ): Optional.Some<E>;
2748
-
2749
- <E extends number>(
2750
- array: readonly E[],
2751
- comparator?: (x: E, y: E) => number,
2752
- ): Optional<E>;
2753
-
2754
- <E>(
2755
- array: NonEmptyArray<E>,
2756
- comparator: (x: E, y: E) => number,
2757
- ): Optional.Some<E>;
2758
-
2759
- <E>(array: readonly E[], comparator: (x: E, y: E) => number): Optional<E>;
2760
- };
2628
+ }
2761
2629
 
2762
2630
  /**
2763
2631
  * Finds the maximum value in an array.
@@ -2777,34 +2645,34 @@ export namespace Arr {
2777
2645
  * Arr.max([]); // Optional.none
2778
2646
  * ```
2779
2647
  */
2780
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2781
- export const max: MaxFnOverload = (<E extends number>(
2782
- array: readonly E[],
2648
+ export function max<E extends number>(
2649
+ array: NonEmptyArray<E>,
2783
2650
  comparator?: (x: E, y: E) => number,
2784
- ): Optional<E> => {
2785
- const cmp = comparator ?? ((x, y) => Num.from(x) - Num.from(y));
2786
- // Find max by finding min with an inverted comparator
2787
- return min(array, (x, y) => -cmp(x, y));
2788
- }) as MaxFnOverload;
2651
+ ): Optional.Some<E>;
2789
2652
 
2790
- type MaxFnOverload = {
2791
- <E extends number>(
2792
- array: NonEmptyArray<E>,
2793
- comparator?: (x: E, y: E) => number,
2794
- ): Optional.Some<E>;
2653
+ export function max<E extends number>(
2654
+ array: readonly E[],
2655
+ comparator?: (x: E, y: E) => number,
2656
+ ): Optional<E>;
2795
2657
 
2796
- <E extends number>(
2797
- array: readonly E[],
2798
- comparator?: (x: E, y: E) => number,
2799
- ): Optional<E>;
2658
+ export function max<E>(
2659
+ array: NonEmptyArray<E>,
2660
+ comparator: (x: E, y: E) => number,
2661
+ ): Optional.Some<E>;
2800
2662
 
2801
- <E>(
2802
- array: NonEmptyArray<E>,
2803
- comparator: (x: E, y: E) => number,
2804
- ): Optional.Some<E>;
2663
+ export function max<E>(
2664
+ array: readonly E[],
2665
+ comparator: (x: E, y: E) => number,
2666
+ ): Optional<E>;
2805
2667
 
2806
- <E>(array: readonly E[], comparator: (x: E, y: E) => number): Optional<E>;
2807
- };
2668
+ export function max<E extends number>(
2669
+ array: readonly E[],
2670
+ comparator?: (x: E, y: E) => number,
2671
+ ): Optional<E> {
2672
+ const cmp = comparator ?? ((x, y) => Num.from(x) - Num.from(y));
2673
+ // Find max by finding min with an inverted comparator
2674
+ return min(array, (x, y) => -cmp(x, y));
2675
+ }
2808
2676
 
2809
2677
  /**
2810
2678
  * Finds the element with the minimum value according to a mapped numeric value.
@@ -2826,43 +2694,40 @@ export namespace Arr {
2826
2694
  * Arr.minBy([], p => p.age); // Optional.none
2827
2695
  * ```
2828
2696
  */
2697
+ export function minBy<E>(
2698
+ array: NonEmptyArray<E>,
2699
+ comparatorValueMapper: (value: E) => number,
2700
+ ): Optional.Some<E>;
2701
+
2702
+ export function minBy<E>(
2703
+ array: readonly E[],
2704
+ comparatorValueMapper: (value: E) => number,
2705
+ ): Optional<E>;
2706
+
2707
+ export function minBy<E, V>(
2708
+ array: NonEmptyArray<E>,
2709
+ comparatorValueMapper: (value: E) => V,
2710
+ comparator: (x: V, y: V) => number,
2711
+ ): Optional.Some<E>;
2829
2712
 
2830
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2831
- export const minBy: MinByFnOverload = (<E, V>(
2713
+ export function minBy<E, V>(
2714
+ array: readonly E[],
2715
+ comparatorValueMapper: (value: E) => V,
2716
+ comparator: (x: V, y: V) => number,
2717
+ ): Optional<E>;
2718
+
2719
+ export function minBy<E, V>(
2832
2720
  array: readonly E[],
2833
2721
  comparatorValueMapper: (value: E) => V,
2834
2722
  comparator?: (x: V, y: V) => number,
2835
- ): Optional<E> =>
2836
- min(array, (x, y) =>
2723
+ ): Optional<E> {
2724
+ return min(array, (x, y) =>
2837
2725
  comparator === undefined
2838
2726
  ? Num.from(comparatorValueMapper(x)) -
2839
2727
  Num.from(comparatorValueMapper(y))
2840
2728
  : comparator(comparatorValueMapper(x), comparatorValueMapper(y)),
2841
- )) as MinByFnOverload;
2842
-
2843
- type MinByFnOverload = {
2844
- <E>(
2845
- array: NonEmptyArray<E>,
2846
- comparatorValueMapper: (value: E) => number,
2847
- ): Optional.Some<E>;
2848
-
2849
- <E>(
2850
- array: readonly E[],
2851
- comparatorValueMapper: (value: E) => number,
2852
- ): Optional<E>;
2853
-
2854
- <E, V>(
2855
- array: NonEmptyArray<E>,
2856
- comparatorValueMapper: (value: E) => V,
2857
- comparator: (x: V, y: V) => number,
2858
- ): Optional.Some<E>;
2859
-
2860
- <E, V>(
2861
- array: readonly E[],
2862
- comparatorValueMapper: (value: E) => V,
2863
- comparator: (x: V, y: V) => number,
2864
- ): Optional<E>;
2865
- };
2729
+ );
2730
+ }
2866
2731
 
2867
2732
  /**
2868
2733
  * Finds the element with the maximum value according to a mapped numeric value.
@@ -2884,42 +2749,40 @@ export namespace Arr {
2884
2749
  * Arr.maxBy([], p => p.age); // Optional.none
2885
2750
  * ```
2886
2751
  */
2887
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2888
- export const maxBy: MaxByFnOverload = (<E, V>(
2752
+ export function maxBy<E>(
2753
+ array: NonEmptyArray<E>,
2754
+ comparatorValueMapper: (value: E) => number,
2755
+ ): Optional.Some<E>;
2756
+
2757
+ export function maxBy<E>(
2758
+ array: readonly E[],
2759
+ comparatorValueMapper: (value: E) => number,
2760
+ ): Optional<E>;
2761
+
2762
+ export function maxBy<E, V>(
2763
+ array: NonEmptyArray<E>,
2764
+ comparatorValueMapper: (value: E) => V,
2765
+ comparator: (x: V, y: V) => number,
2766
+ ): Optional.Some<E>;
2767
+
2768
+ export function maxBy<E, V>(
2769
+ array: readonly E[],
2770
+ comparatorValueMapper: (value: E) => V,
2771
+ comparator: (x: V, y: V) => number,
2772
+ ): Optional<E>;
2773
+
2774
+ export function maxBy<E, V>(
2889
2775
  array: readonly E[],
2890
2776
  comparatorValueMapper: (value: E) => V,
2891
2777
  comparator?: (x: V, y: V) => number,
2892
- ): Optional<E> =>
2893
- max(array, (x, y) =>
2778
+ ): Optional<E> {
2779
+ return max(array, (x, y) =>
2894
2780
  comparator === undefined
2895
2781
  ? Num.from(comparatorValueMapper(x)) -
2896
2782
  Num.from(comparatorValueMapper(y))
2897
2783
  : comparator(comparatorValueMapper(x), comparatorValueMapper(y)),
2898
- )) as MaxByFnOverload;
2899
-
2900
- type MaxByFnOverload = {
2901
- <E>(
2902
- array: NonEmptyArray<E>,
2903
- comparatorValueMapper: (value: E) => number,
2904
- ): Optional.Some<E>;
2905
-
2906
- <E>(
2907
- array: readonly E[],
2908
- comparatorValueMapper: (value: E) => number,
2909
- ): Optional<E>;
2910
-
2911
- <E, V>(
2912
- array: NonEmptyArray<E>,
2913
- comparatorValueMapper: (value: E) => V,
2914
- comparator: (x: V, y: V) => number,
2915
- ): Optional.Some<E>;
2916
-
2917
- <E, V>(
2918
- array: readonly E[],
2919
- comparatorValueMapper: (value: E) => V,
2920
- comparator: (x: V, y: V) => number,
2921
- ): Optional<E>;
2922
- };
2784
+ );
2785
+ }
2923
2786
 
2924
2787
  /**
2925
2788
  * Counts the number of elements in an array that satisfy a predicate.
@@ -2938,15 +2801,23 @@ export namespace Arr {
2938
2801
  * console.log(result); // 3
2939
2802
  * ```
2940
2803
  */
2941
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2942
- export const count: CountFnOverload = (<E,>(
2804
+ export function count<E>(
2805
+ array: readonly E[],
2806
+ predicate: (value: E, index: SizeType.Arr) => boolean,
2807
+ ): SizeType.Arr;
2808
+
2809
+ export function count<E>(
2810
+ predicate: (value: E, index: SizeType.Arr) => boolean,
2811
+ ): (array: readonly E[]) => SizeType.Arr;
2812
+
2813
+ export function count<E>(
2943
2814
  ...args:
2944
2815
  | readonly [
2945
2816
  array: readonly E[],
2946
2817
  predicate: (value: E, index: SizeType.Arr) => boolean,
2947
2818
  ]
2948
2819
  | readonly [predicate: (value: E, index: SizeType.Arr) => boolean]
2949
- ) => {
2820
+ ): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr) {
2950
2821
  switch (args.length) {
2951
2822
  case 2: {
2952
2823
  const [array, predicate] = args;
@@ -2961,19 +2832,7 @@ export namespace Arr {
2961
2832
  return (array: readonly E[]) => count(array, predicate);
2962
2833
  }
2963
2834
  }
2964
- }) as CountFnOverload;
2965
-
2966
- type CountFnOverload = {
2967
- <E>(
2968
- array: readonly E[],
2969
- predicate: (value: E, index: SizeType.Arr) => boolean,
2970
- ): SizeType.Arr;
2971
-
2972
- // curried version
2973
- <E>(
2974
- predicate: (value: E, index: SizeType.Arr) => boolean,
2975
- ): (array: readonly E[]) => SizeType.Arr;
2976
- };
2835
+ }
2977
2836
 
2978
2837
  /**
2979
2838
  * Groups elements of an array by a key derived from each element and counts the elements in each group.
@@ -2995,19 +2854,27 @@ export namespace Arr {
2995
2854
  * // IMap { 'a' => 2, 'b' => 1 }
2996
2855
  * ```
2997
2856
  */
2998
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
2999
- export const countBy: CountByFnOverload = (<E, G extends MapSetKeyType>(
2857
+ export function countBy<E, G extends MapSetKeyType>(
2858
+ array: readonly E[],
2859
+ grouper: (value: E, index: SizeType.Arr) => G,
2860
+ ): IMap<G, SizeType.Arr>;
2861
+
2862
+ export function countBy<E, G extends MapSetKeyType>(
2863
+ grouper: (value: E, index: SizeType.Arr) => G,
2864
+ ): (array: readonly E[]) => IMap<G, SizeType.Arr>;
2865
+
2866
+ export function countBy<E, G extends MapSetKeyType>(
3000
2867
  ...args:
3001
2868
  | readonly [
3002
2869
  array: readonly E[],
3003
2870
  grouper: (value: E, index: SizeType.Arr) => G,
3004
2871
  ]
3005
2872
  | readonly [grouper: (value: E, index: SizeType.Arr) => G]
3006
- ) => {
2873
+ ): IMap<G, SizeType.Arr> | ((array: readonly E[]) => IMap<G, SizeType.Arr>) {
3007
2874
  switch (args.length) {
3008
2875
  case 2: {
3009
2876
  const [array, grouper] = args;
3010
- const mut_groups = new Map<MapSetKeyType, SizeType.Arr>();
2877
+ const mut_groups = new Map<G, SizeType.Arr>();
3011
2878
 
3012
2879
  for (const [index, e] of array.entries()) {
3013
2880
  const key = grouper(e, asUint32(index));
@@ -3023,19 +2890,7 @@ export namespace Arr {
3023
2890
  return (array: readonly E[]) => countBy(array, grouper);
3024
2891
  }
3025
2892
  }
3026
- }) as CountByFnOverload;
3027
-
3028
- type CountByFnOverload = {
3029
- <E, G extends MapSetKeyType>(
3030
- array: readonly E[],
3031
- grouper: (value: E, index: SizeType.Arr) => G,
3032
- ): IMap<G, SizeType.Arr>;
3033
-
3034
- // curried version
3035
- <E, G extends MapSetKeyType>(
3036
- grouper: (value: E, index: SizeType.Arr) => G,
3037
- ): (array: readonly E[]) => IMap<G, SizeType.Arr>;
3038
- };
2893
+ }
3039
2894
 
3040
2895
  /**
3041
2896
  * Calculates the sum of numbers in an array.
@@ -3048,17 +2903,19 @@ export namespace Arr {
3048
2903
  * Arr.sum([-1, 0, 1]); // 0
3049
2904
  * ```
3050
2905
  */
3051
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3052
- export const sum: SumFnOverload = ((array: readonly number[]): number =>
3053
- array.reduce((prev, curr) => prev + curr, 0)) as SumFnOverload;
2906
+ export function sum(array: readonly []): 0;
3054
2907
 
3055
- type SumFnOverload = {
3056
- (array: readonly []): 0;
3057
- <N extends number>(array: readonly [N]): N;
3058
- (array: readonly Uint[]): Uint;
3059
- (array: readonly Int[]): Int;
3060
- (array: readonly number[]): number;
3061
- };
2908
+ export function sum<N extends number>(array: readonly [N]): N;
2909
+
2910
+ export function sum(array: readonly Uint[]): Uint;
2911
+
2912
+ export function sum(array: readonly Int[]): Int;
2913
+
2914
+ export function sum(array: readonly number[]): number;
2915
+
2916
+ export function sum(array: readonly number[]): number {
2917
+ return array.reduce((prev, curr) => prev + curr, 0);
2918
+ }
3062
2919
 
3063
2920
  /**
3064
2921
  * Joins array elements into a string.
@@ -3080,20 +2937,28 @@ export namespace Arr {
3080
2937
  * console.log(Result.unwrapOr(result2, '')); // "a,b,c"
3081
2938
  * ```
3082
2939
  */
3083
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3084
- export const join: JoinFnOverload = (<E,>(
2940
+ export function join<E>(
2941
+ array: readonly E[],
2942
+ separator?: string,
2943
+ ): Result<string, Error>;
2944
+
2945
+ export function join(
2946
+ separator?: string,
2947
+ ): <E>(array: readonly E[]) => Result<string, Error>;
2948
+
2949
+ export function join<E>(
3085
2950
  ...args:
3086
2951
  | readonly [array: readonly E[], separator?: string]
3087
2952
  | readonly [separator?: string]
3088
- ) => {
2953
+ ): Result<string, Error> | ((array: readonly E[]) => Result<string, Error>) {
3089
2954
  switch (args.length) {
3090
2955
  case 0:
3091
- return <E2,>(array: readonly E2[]) => joinImpl(array, undefined);
2956
+ return (array: readonly E[]) => joinImpl(array, undefined);
3092
2957
 
3093
2958
  case 1: {
3094
2959
  const [arg] = args;
3095
2960
  if (isString(arg) || isUndefined(arg)) {
3096
- return <E2,>(array: readonly E2[]) => joinImpl(array, arg);
2961
+ return (array: readonly E[]) => joinImpl(array, arg);
3097
2962
  }
3098
2963
  return joinImpl(arg, undefined);
3099
2964
  }
@@ -3102,7 +2967,7 @@ export namespace Arr {
3102
2967
  return joinImpl(array, separator);
3103
2968
  }
3104
2969
  }
3105
- }) as JoinFnOverload;
2970
+ }
3106
2971
 
3107
2972
  const joinImpl = <E,>(
3108
2973
  array: readonly E[],
@@ -3122,13 +2987,6 @@ export namespace Arr {
3122
2987
  }
3123
2988
  };
3124
2989
 
3125
- type JoinFnOverload = {
3126
- <E>(array: readonly E[], separator?: string): Result<string, Error>;
3127
-
3128
- // curried version
3129
- (separator?: string): <E>(array: readonly E[]) => Result<string, Error>;
3130
- };
3131
-
3132
2990
  // transformation
3133
2991
 
3134
2992
  /**
@@ -3179,15 +3037,23 @@ export namespace Arr {
3179
3037
  * console.log(result); // [1, 3, 5]
3180
3038
  * ```
3181
3039
  */
3182
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3183
- export const filterNot: FilterNotFnOverload = (<E,>(
3040
+ export function filterNot<E>(
3041
+ array: readonly E[],
3042
+ predicate: (a: E, index: SizeType.Arr) => boolean,
3043
+ ): readonly E[];
3044
+
3045
+ export function filterNot<E>(
3046
+ predicate: (a: E, index: SizeType.Arr) => boolean,
3047
+ ): (array: readonly E[]) => readonly E[];
3048
+
3049
+ export function filterNot<E>(
3184
3050
  ...args:
3185
3051
  | readonly [
3186
3052
  array: readonly E[],
3187
3053
  predicate: (a: E, index: SizeType.Arr) => boolean,
3188
3054
  ]
3189
3055
  | readonly [predicate: (a: E, index: SizeType.Arr) => boolean]
3190
- ) => {
3056
+ ): readonly E[] | ((array: readonly E[]) => readonly E[]) {
3191
3057
  switch (args.length) {
3192
3058
  case 2: {
3193
3059
  const [array, predicate] = args;
@@ -3198,19 +3064,7 @@ export namespace Arr {
3198
3064
  return (array: readonly E[]) => filterNot(array, predicate);
3199
3065
  }
3200
3066
  }
3201
- }) as FilterNotFnOverload;
3202
-
3203
- type FilterNotFnOverload = {
3204
- <E>(
3205
- array: readonly E[],
3206
- predicate: (a: E, index: SizeType.Arr) => boolean,
3207
- ): readonly E[];
3208
-
3209
- // curried version
3210
- <E>(
3211
- predicate: (a: E, index: SizeType.Arr) => boolean,
3212
- ): (array: readonly E[]) => readonly E[];
3213
- };
3067
+ }
3214
3068
 
3215
3069
  /**
3216
3070
  * Concatenates two arrays.
@@ -3245,24 +3099,29 @@ export namespace Arr {
3245
3099
  * @returns An array of arrays, where each inner array has up to `chunkSize` elements.
3246
3100
  * @example
3247
3101
  * ```ts
3248
- * // Regular usage
3249
3102
  * Arr.partition([1, 2, 3, 4, 5, 6], 2); // [[1, 2], [3, 4], [5, 6]]
3250
- *
3251
- * // Curried usage for pipe composition
3252
- * const chunkBy3 = Arr.partition(3);
3253
- * const result = pipe([1, 2, 3, 4, 5, 6, 7]).map(chunkBy3).value;
3254
- * console.log(result); // [[1, 2, 3], [4, 5, 6], [7]]
3103
+ * Arr.partition([1, 2, 3, 4, 5, 6, 7], 3); // [[1, 2, 3], [4, 5, 6], [7]]
3255
3104
  * ```
3256
3105
  */
3257
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3258
- export const partition: PartitionFnOverload = (<
3106
+ export function partition<
3107
+ N extends WithSmallInt<PositiveInt & SizeType.Arr>,
3108
+ E,
3109
+ >(array: readonly E[], chunkSize: N): readonly (readonly E[])[];
3110
+
3111
+ export function partition<N extends WithSmallInt<PositiveInt & SizeType.Arr>>(
3112
+ chunkSize: N,
3113
+ ): <E>(array: readonly E[]) => readonly (readonly E[])[];
3114
+
3115
+ export function partition<
3259
3116
  N extends WithSmallInt<PositiveInt & SizeType.Arr>,
3260
3117
  E,
3261
3118
  >(
3262
3119
  ...args:
3263
3120
  | readonly [array: readonly E[], chunkSize: N]
3264
3121
  | readonly [chunkSize: N]
3265
- ) => {
3122
+ ):
3123
+ | readonly (readonly E[])[]
3124
+ | ((array: readonly E[]) => readonly (readonly E[])[]) {
3266
3125
  switch (args.length) {
3267
3126
  case 2: {
3268
3127
  const [array, chunkSize] = args;
@@ -3277,19 +3136,7 @@ export namespace Arr {
3277
3136
  return (array: readonly E[]) => partition(array, chunkSize);
3278
3137
  }
3279
3138
  }
3280
- }) as PartitionFnOverload;
3281
-
3282
- type PartitionFnOverload = {
3283
- <N extends WithSmallInt<PositiveInt & SizeType.Arr>, E>(
3284
- array: readonly E[],
3285
- chunkSize: N,
3286
- ): readonly (readonly E[])[];
3287
-
3288
- // curried version
3289
- <N extends WithSmallInt<PositiveInt & SizeType.Arr>>(
3290
- chunkSize: N,
3291
- ): <E>(array: readonly E[]) => readonly (readonly E[])[];
3292
- };
3139
+ }
3293
3140
 
3294
3141
  /**
3295
3142
  * Sorts an array by a value derived from its elements, using a numeric mapping.
@@ -3307,35 +3154,34 @@ export namespace Arr {
3307
3154
  * // [{ name: 'Adam', score: 90 }, { name: 'Bob', score: 80 }, { name: 'Eve', score: 70 }]
3308
3155
  * ```
3309
3156
  */
3310
- export const toSortedBy: ToSortedByFnOverload = <E, const V>(
3157
+ export function toSortedBy<E>(
3158
+ array: readonly E[],
3159
+ comparatorValueMapper: (value: E) => number,
3160
+ comparator?: (x: number, y: number) => number,
3161
+ ): readonly E[];
3162
+
3163
+ export function toSortedBy<E, const V>(
3164
+ array: readonly E[],
3165
+ comparatorValueMapper: (value: E) => V,
3166
+ comparator: (x: V, y: V) => number,
3167
+ ): readonly E[];
3168
+
3169
+ export function toSortedBy<E, const V>(
3311
3170
  array: readonly E[],
3312
3171
  comparatorValueMapper: (value: E) => V,
3313
3172
  comparator?: (x: V, y: V) => number,
3314
- ): readonly E[] =>
3315
- array.toSorted((x, y) =>
3173
+ ): readonly E[] {
3174
+ return array.toSorted((x, y) =>
3316
3175
  comparator === undefined
3317
- ? // This branch assumes B is number if comparator is undefined.
3318
- // The overloads should handle this, but explicit cast might be needed if B is not number.
3176
+ ? // This branch assumes V is number if comparator is undefined.
3177
+ // The overloads should handle this, but explicit cast might be needed if V is not number.
3319
3178
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3320
3179
  (comparatorValueMapper(x) as number) -
3321
3180
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3322
3181
  (comparatorValueMapper(y) as number)
3323
3182
  : comparator(comparatorValueMapper(x), comparatorValueMapper(y)),
3324
3183
  );
3325
-
3326
- type ToSortedByFnOverload = {
3327
- <E>(
3328
- array: readonly E[],
3329
- comparatorValueMapper: (value: E) => number,
3330
- comparator?: (x: number, y: number) => number,
3331
- ): readonly E[];
3332
-
3333
- <E, const V>(
3334
- array: readonly E[],
3335
- comparatorValueMapper: (value: E) => V,
3336
- comparator: (x: V, y: V) => number,
3337
- ): readonly E[];
3338
- };
3184
+ }
3339
3185
 
3340
3186
  /**
3341
3187
  * Returns an array of successively reduced values from an array, starting with an initial value.
@@ -3493,8 +3339,18 @@ export namespace Arr {
3493
3339
  * @see {@link SizeType.Arr} for the index parameter type
3494
3340
  * @see Array.prototype.reduce for the standard reduce function
3495
3341
  */
3496
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3497
- export const scan: ScanFnOverload = (<E, S>(
3342
+ export function scan<E, S>(
3343
+ array: readonly E[],
3344
+ reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S,
3345
+ init: S,
3346
+ ): NonEmptyArray<S>;
3347
+
3348
+ export function scan<E, S>(
3349
+ reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S,
3350
+ init: S,
3351
+ ): (array: readonly E[]) => NonEmptyArray<S>;
3352
+
3353
+ export function scan<E, S>(
3498
3354
  ...args:
3499
3355
  | readonly [
3500
3356
  array: readonly E[],
@@ -3513,7 +3369,7 @@ export namespace Arr {
3513
3369
  ) => S,
3514
3370
  init: S,
3515
3371
  ]
3516
- ) => {
3372
+ ): NonEmptyArray<S> | ((array: readonly E[]) => NonEmptyArray<S>) {
3517
3373
  switch (args.length) {
3518
3374
  case 3: {
3519
3375
  const [array, reducer, init] = args;
@@ -3535,29 +3391,7 @@ export namespace Arr {
3535
3391
  return (array: readonly E[]) => scan(array, reducer, init);
3536
3392
  }
3537
3393
  }
3538
- }) as ScanFnOverload;
3539
-
3540
- type ScanFnOverload = {
3541
- <E, S>(
3542
- array: readonly E[],
3543
- reducer: (
3544
- accumulator: S,
3545
- currentValue: E,
3546
- currentIndex: SizeType.Arr,
3547
- ) => S,
3548
- init: S,
3549
- ): NonEmptyArray<S>;
3550
-
3551
- // curried version
3552
- <E, S>(
3553
- reducer: (
3554
- accumulator: S,
3555
- currentValue: E,
3556
- currentIndex: SizeType.Arr,
3557
- ) => S,
3558
- init: S,
3559
- ): (array: readonly E[]) => NonEmptyArray<S>;
3560
- };
3394
+ }
3561
3395
 
3562
3396
  /**
3563
3397
  * Groups elements of an array by a key derived from each element, returning an immutable {@link IMap}.
@@ -3708,15 +3542,23 @@ export namespace Arr {
3708
3542
  * @see {@link IMap.map} for transforming grouped data
3709
3543
  * @see {@link Optional} for handling potentially missing groups
3710
3544
  */
3711
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3712
- export const groupBy: GroupByFnOverload = (<E, G extends MapSetKeyType>(
3545
+ export function groupBy<E, G extends MapSetKeyType>(
3546
+ array: readonly E[],
3547
+ grouper: (value: E, index: SizeType.Arr) => G,
3548
+ ): IMap<G, readonly E[]>;
3549
+
3550
+ export function groupBy<E, G extends MapSetKeyType>(
3551
+ grouper: (value: E, index: SizeType.Arr) => G,
3552
+ ): (array: readonly E[]) => IMap<G, readonly E[]>;
3553
+
3554
+ export function groupBy<E, G extends MapSetKeyType>(
3713
3555
  ...args:
3714
3556
  | readonly [
3715
3557
  array: readonly E[],
3716
3558
  grouper: (value: E, index: SizeType.Arr) => G,
3717
3559
  ]
3718
3560
  | readonly [grouper: (value: E, index: SizeType.Arr) => G]
3719
- ) => {
3561
+ ): IMap<G, readonly E[]> | ((array: readonly E[]) => IMap<G, readonly E[]>) {
3720
3562
  switch (args.length) {
3721
3563
  case 2: {
3722
3564
  const [array, grouper] = args;
@@ -3739,19 +3581,7 @@ export namespace Arr {
3739
3581
  return (array: readonly E[]) => groupBy(array, grouper);
3740
3582
  }
3741
3583
  }
3742
- }) as GroupByFnOverload;
3743
-
3744
- type GroupByFnOverload = {
3745
- <E, G extends MapSetKeyType>(
3746
- array: readonly E[],
3747
- grouper: (value: E, index: SizeType.Arr) => G,
3748
- ): IMap<G, readonly E[]>;
3749
-
3750
- // curried version
3751
- <E, G extends MapSetKeyType>(
3752
- grouper: (value: E, index: SizeType.Arr) => G,
3753
- ): (array: readonly E[]) => IMap<G, readonly E[]>;
3754
- };
3584
+ }
3755
3585
 
3756
3586
  /**
3757
3587
  * Creates a new array with unique elements from the input array. Order is preserved from the first occurrence.
@@ -3762,7 +3592,6 @@ export namespace Arr {
3762
3592
  * @example
3763
3593
  * ```ts
3764
3594
  * Arr.uniq([1, 2, 2, 3, 1, 4]); // [1, 2, 3, 4]
3765
- * Arr.uniq(['a', 'b', 'a']); // ['a', 'b']
3766
3595
  * ```
3767
3596
  */
3768
3597
  export const uniq = <P extends Primitive>(
@@ -3790,11 +3619,20 @@ export namespace Arr {
3790
3619
  * Arr.uniqBy(users, user => user.id); // [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
3791
3620
  * ```
3792
3621
  */
3793
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
3794
- export const uniqBy: UniqByFnOverload = (<E, P extends Primitive>(
3622
+ export function uniqBy<E, P extends Primitive>(
3623
+ array: NonEmptyArray<E>,
3624
+ mapFn: (value: E) => P,
3625
+ ): NonEmptyArray<E>;
3626
+
3627
+ export function uniqBy<E, P extends Primitive>(
3795
3628
  array: readonly E[],
3796
3629
  mapFn: (value: E) => P,
3797
- ): readonly E[] => {
3630
+ ): readonly E[];
3631
+
3632
+ export function uniqBy<E, P extends Primitive>(
3633
+ array: readonly E[],
3634
+ mapFn: (value: E) => P,
3635
+ ): readonly E[] {
3798
3636
  const mut_mappedValues = new Set<P>();
3799
3637
 
3800
3638
  return array.filter((val) => {
@@ -3805,19 +3643,7 @@ export namespace Arr {
3805
3643
 
3806
3644
  return true;
3807
3645
  });
3808
- }) as UniqByFnOverload;
3809
-
3810
- type UniqByFnOverload = {
3811
- <E, P extends Primitive>(
3812
- array: NonEmptyArray<E>,
3813
- mapFn: (value: E) => P,
3814
- ): NonEmptyArray<E>;
3815
-
3816
- <E, P extends Primitive>(
3817
- array: readonly E[],
3818
- mapFn: (value: E) => P,
3819
- ): readonly E[];
3820
- };
3646
+ }
3821
3647
 
3822
3648
  // set operations & equality
3823
3649