ts-data-forge 1.5.2 → 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 (37) hide show
  1. package/README.md +13 -1
  2. package/dist/array/array-utils.d.mts +661 -166
  3. package/dist/array/array-utils.d.mts.map +1 -1
  4. package/dist/array/array-utils.mjs +719 -79
  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/queue.mjs +0 -1
  11. package/dist/collections/queue.mjs.map +1 -1
  12. package/dist/collections/stack.mjs +4 -5
  13. package/dist/collections/stack.mjs.map +1 -1
  14. package/dist/globals.d.mts +10 -9
  15. package/dist/index.mjs +0 -1
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/json/json.mjs +0 -1
  18. package/dist/json/json.mjs.map +1 -1
  19. package/dist/number/num.d.mts +1 -1
  20. package/package.json +2 -2
  21. package/src/array/array-utils-modification.test.mts +93 -67
  22. package/src/array/array-utils-overload-type-error.test.mts +2 -2
  23. package/src/array/array-utils-reducing-value.test.mts +31 -37
  24. package/src/array/array-utils-slice-clamped.test.mts +94 -70
  25. package/src/array/array-utils-transformation.test.mts +557 -10
  26. package/src/array/array-utils.mts +1457 -516
  27. package/src/array/index.mts +0 -1
  28. package/src/collections/queue.mts +2 -2
  29. package/src/collections/stack.mts +8 -8
  30. package/src/globals.d.mts +10 -9
  31. package/src/number/num.mts +1 -1
  32. package/dist/array/tuple-utils.d.mts +0 -407
  33. package/dist/array/tuple-utils.d.mts.map +0 -1
  34. package/dist/array/tuple-utils.mjs +0 -345
  35. package/dist/array/tuple-utils.mjs.map +0 -1
  36. package/src/array/tuple-utils.mts +0 -498
  37. package/src/array/tuple-utils.test.mts +0 -518
@@ -9,6 +9,9 @@ import { Optional, Result } from '../functional/index.mjs';
9
9
  * ensuring immutability.
10
10
  */
11
11
  export declare namespace Arr {
12
+ type ArrayIndex<Ar extends readonly unknown[]> = IsFixedLengthList<Ar> extends true ? IndexOfTuple<Ar> : SizeType.Arr;
13
+ type ArgArrayIndex<Ar extends readonly unknown[]> = IsFixedLengthList<Ar> extends true ? IndexOfTuple<Ar> : SizeType.ArgArr;
14
+ type ArgArrayIndexWithNegative<Ar extends readonly unknown[]> = IsFixedLengthList<Ar> extends true ? IndexOfTuple<[...Ar, 0]> | NegativeIndexOfTuple<Ar> : SizeType.ArgArrWithNegative;
12
15
  /**
13
16
  * Returns the size (length) of an array as a type-safe branded integer.
14
17
  *
@@ -34,7 +37,7 @@ export declare namespace Arr {
34
37
  * // Type: IntersectBrand<PositiveNumber, SizeType.Arr>
35
38
  * // Value: 3 (branded, guaranteed positive)
36
39
  *
37
- * const nonEmpty: NonEmptyArray<string> = ['a', 'b'] as NonEmptyArray<string>;
40
+ * const nonEmpty: NonEmptyArray<string> = ['a', 'b'];
38
41
  * const nonEmptySize = Arr.size(nonEmpty);
39
42
  * // Type: IntersectBrand<PositiveNumber, SizeType.Arr>
40
43
  * // Guaranteed to be > 0
@@ -64,13 +67,6 @@ export declare namespace Arr {
64
67
  * const indices = Arr.seq(dataSize); // Creates [0, 1, 2]
65
68
  * const zeros = Arr.zeros(dataSize); // Creates [0, 0, 0]
66
69
  *
67
- * // Safe for bounds checking
68
- * const isValidIndex = (index: number) => index >= 0 && index < dataSize;
69
- *
70
- * // Comparison with other sizes
71
- * const otherArray = ['a', 'b'];
72
- * const sizeDiff = Uint32.sub(Arr.size(data), Arr.size(otherArray)); // 1
73
- *
74
70
  * // Functional composition
75
71
  * const arrays = [
76
72
  * [1, 2],
@@ -97,9 +93,7 @@ export declare namespace Arr {
97
93
  * @see {@link isEmpty} for checking if size is 0
98
94
  * @see {@link isNonEmpty} for checking if size > 0
99
95
  */
100
- export function size<Ar extends NonEmptyArray<unknown>>(array: Ar): IntersectBrand<PositiveNumber, SizeType.Arr>;
101
- export function size<Ar extends readonly unknown[]>(array: Ar): SizeType.Arr;
102
- export const length: typeof size;
96
+ export const size: <Ar extends readonly unknown[]>(array: Ar) => Ar extends NonEmptyArray<unknown> ? IntersectBrand<PositiveNumber, SizeType.Arr> : SizeType.Arr;
103
97
  /**
104
98
  * Type guard that checks if a value is an array, excluding types that cannot be arrays.
105
99
  * This function refines the type by filtering out non-array types from unions.
@@ -149,26 +143,11 @@ export declare namespace Arr {
149
143
  * if (Arr.isEmpty(arr)) {
150
144
  * // arr is now typed as readonly []
151
145
  * console.log('Array is empty');
146
+ * // arr[0]; // type error!
152
147
  * return 0;
153
- * } else {
154
- * // arr is now typed as NonEmptyArray<number>
155
- * return arr[0]; // Safe access - TypeScript knows it's non-empty
156
148
  * }
157
149
  * }
158
150
  *
159
- * // Conditional processing
160
- * const data = [10, 20, 30];
161
- * if (!Arr.isEmpty(data)) {
162
- * // Safe to access elements
163
- * const firstElement = data[0]; // No undefined risk
164
- * const lastElement = data[data.length - 1];
165
- * }
166
- *
167
- * // Filtering empty arrays
168
- * const arrayList: readonly number[][] = [[1, 2], [], [3], []];
169
- * const nonEmptyArrays = arrayList.filter(arr => !Arr.isEmpty(arr));
170
- * // nonEmptyArrays: [[1, 2], [3]]
171
- *
172
151
  * // Early returns
173
152
  * function sumArray(numbers: readonly number[]): number {
174
153
  * if (Arr.isEmpty(numbers)) {
@@ -177,12 +156,6 @@ export declare namespace Arr {
177
156
  * return numbers.reduce((sum, n) => sum + n, 0);
178
157
  * }
179
158
  *
180
- * // Type inference examples
181
- * const testEmpty = [] as const;
182
- * const testNonEmpty = [1, 2] as const;
183
- *
184
- * expectType<Parameters<typeof Arr.isEmpty>[0], readonly unknown[]>('=');
185
- * expectType<ReturnType<typeof Arr.isEmpty>, boolean>('=');
186
159
  * ```
187
160
  *
188
161
  * @see {@link isNonEmpty} for the opposite check (non-empty arrays)
@@ -223,16 +196,14 @@ export declare namespace Arr {
223
196
  *
224
197
  * // Safe operations on non-empty arrays
225
198
  * function processData(data: readonly string[]) {
226
- * if (Arr.isNonEmpty(data)) {
227
- * // All of these are now safe without undefined checks
228
- * const first = data[0];
229
- * const last = data[data.length - 1];
230
- * const middle = data[Math.floor(data.length / 2)];
231
- *
232
- * // Can safely use non-empty array methods
233
- * const joined = data.join(', ');
234
- * const reduced = data.reduce((acc, item) => acc + item.length, 0);
235
- * }
199
+ * if (!Arr.isNonEmpty(data)) return; // early return pattern
200
+ *
201
+ * // This is now safe without undefined checks
202
+ * const first = data[0];
203
+ *
204
+ * // Can safely use non-empty array methods
205
+ * const lastElement = Arr.last(data);
206
+ *
236
207
  * }
237
208
  *
238
209
  * // Filtering and working with arrays
@@ -257,7 +228,7 @@ export declare namespace Arr {
257
228
  * }
258
229
  *
259
230
  * // numbers is now NonEmptyArray<number>
260
- * return numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
231
+ * return Arr.sum(numbers) / Arr.size(numbers);
261
232
  * }
262
233
  *
263
234
  * // Functional composition
@@ -318,7 +289,7 @@ export declare namespace Arr {
318
289
  * Arr.isArrayOfLength([1, 2], 3); // false
319
290
  * ```
320
291
  */
321
- export const isArrayOfLength: <E, N extends SizeType.ArgArrNonNegative>(array: readonly E[], len: N) => array is ArrayOfLength<N, E>;
292
+ export const isArrayOfLength: <E, N extends SizeType.ArgArr>(array: readonly E[], len: N) => array is ArrayOfLength<N, E>;
322
293
  /**
323
294
  * Checks if an array has at least a specific length.
324
295
  * @template E The type of elements in the array.
@@ -335,7 +306,7 @@ export declare namespace Arr {
335
306
  * Arr.isArrayAtLeastLength([1], 2); // false
336
307
  * ```
337
308
  */
338
- export const isArrayAtLeastLength: <E, N extends SizeType.ArgArrNonNegative>(array: readonly E[], len: N) => array is ArrayAtLeastLen<N, E>;
309
+ export const isArrayAtLeastLength: <E, N extends SizeType.ArgArr>(array: readonly E[], len: N) => array is ArrayAtLeastLen<N, E>;
339
310
  /**
340
311
  * Checks if an index is within the valid range of an array (i.e., `0 <= index < array.length`).
341
312
  * @template E The type of elements in the array.
@@ -351,7 +322,7 @@ export declare namespace Arr {
351
322
  * Arr.indexIsInRange([], 0); // false
352
323
  * ```
353
324
  */
354
- export const indexIsInRange: <E>(array: readonly E[], index: SizeType.ArgArrNonNegative) => boolean;
325
+ export const indexIsInRange: <E>(array: readonly E[], index: SizeType.ArgArr) => boolean;
355
326
  /**
356
327
  * Creates an array of zeros with the specified length.
357
328
  *
@@ -388,18 +359,7 @@ export declare namespace Arr {
388
359
  * expectType<typeof maybeEmpty, readonly 0[]>('=');
389
360
  * ```
390
361
  */
391
- /**
392
- * Create array of zeros with compile-time length.
393
- */
394
- export function zeros<N extends SmallUint>(len: N): ArrayOfLength<N, 0>;
395
- /**
396
- * Create non-empty array of zeros.
397
- */
398
- export function zeros(len: SizeType.ArgArrPositive): NonEmptyArray<0>;
399
- /**
400
- * Create array of zeros.
401
- */
402
- export function zeros(len: SizeType.ArgArrNonNegative): readonly 0[];
362
+ export const zeros: <N extends SizeType.ArgArr>(len: N) => N extends SmallUint ? ArrayOfLength<N, 0> : N extends SizeType.ArgArrPositive ? NonEmptyArray<0> : readonly 0[];
403
363
  /**
404
364
  * Creates a sequence of consecutive integers from 0 to `len-1`.
405
365
  *
@@ -441,9 +401,7 @@ export declare namespace Arr {
441
401
  * expectType<typeof single, readonly [0]>('=');
442
402
  * ```
443
403
  */
444
- export function seq<N extends SmallUint>(len: N): Seq<N>;
445
- export function seq(len: SizeType.ArgArrPositive): NonEmptyArray<SizeType.Arr>;
446
- export function seq(len: SizeType.ArgArrNonNegative): readonly SizeType.Arr[];
404
+ export const seq: <N extends SizeType.ArgArr>(len: N) => N extends SmallUint ? Seq<N> : N extends SizeType.ArgArrPositive ? NonEmptyArray<SizeType.Arr> : readonly SizeType.Arr[];
447
405
  /**
448
406
  * Creates a new array of the specified length, with each position filled with the provided initial value.
449
407
  *
@@ -492,10 +450,7 @@ export declare namespace Arr {
492
450
  * @see {@link zeros} for creating arrays filled with zeros
493
451
  * @see {@link seq} for creating sequences of consecutive integers
494
452
  */
495
- export function create<const V, N extends SmallUint>(len: N, init: V): ArrayOfLength<N, V>;
496
- export function create<const V>(len: SizeType.ArgArrPositive, init: V): NonEmptyArray<V>;
497
- export function create<const V>(len: SizeType.ArgArrNonNegative, init: V): readonly V[];
498
- export const newArray: typeof create;
453
+ export const create: <const V, N extends SizeType.ArgArr>(len: N, init: V) => N extends SmallUint ? ArrayOfLength<N, V> : N extends SizeType.ArgArrPositive ? NonEmptyArray<V> : readonly V[];
499
454
  /**
500
455
  * Creates an array from a generator function.
501
456
  *
@@ -678,7 +633,10 @@ export declare namespace Arr {
678
633
  *
679
634
  * // Functional programming patterns
680
635
  * const squares = Arr.range(1, 6).map(x => x * x); // [1, 4, 9, 16, 25]
681
- * const fibonacci = Arr.range(0, 10).reduce((acc, _, i) => {\n * if (i <= 1) return [...acc, i];\n * return [...acc, acc[i-1] + acc[i-2]];\n * }, [] as number[]); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
636
+ * const fibonacci = Arr.range(0, 10).reduce((acc, _, i) => {
637
+ * if (i <= 1) return [...acc, i];
638
+ * return [...acc, acc[i-1] + acc[i-2]];
639
+ * }, [] as number[]); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
682
640
  *
683
641
  * // Type inference examples showing precise vs general types
684
642
  * expectType<typeof range1to4, readonly [1, 2, 3, 4]>('='); // Precise tuple
@@ -808,8 +766,8 @@ export declare namespace Arr {
808
766
  * @see {@link Optional.unwrapOr} for safe unwrapping with defaults
809
767
  * @see {@link Optional.map} for transforming Optional values
810
768
  */
811
- export function at<E>(array: readonly E[], index: SizeType.ArgArr): Optional<E>;
812
- export function at(index: SizeType.ArgArr): <E>(array: readonly E[]) => Optional<E>;
769
+ export function at<Ar extends readonly unknown[]>(array: Ar, index: ArgArrayIndexWithNegative<Ar>): Optional<Ar[number]>;
770
+ export function at(index: SizeType.ArgArrWithNegative): <E>(array: readonly E[]) => Optional<E>;
813
771
  /**
814
772
  * Returns the first element of an array wrapped in an Optional.
815
773
  *
@@ -881,10 +839,7 @@ export declare namespace Arr {
881
839
  * @see {@link at} for accessing elements at specific indices
882
840
  * @see {@link tail} for getting all elements except the first
883
841
  */
884
- export function head(array: readonly []): Optional.None;
885
- export function head<E, L extends readonly unknown[]>(array: readonly [E, ...L]): Optional.Some<E>;
886
- export function head<E>(array: NonEmptyArray<E>): Optional.Some<E>;
887
- export function head<E>(array: readonly E[]): Optional<E>;
842
+ export const head: <Ar extends readonly unknown[]>(array: Ar) => Ar extends readonly [] ? Optional.None : Ar extends readonly [infer E, ...unknown[]] ? Optional.Some<E> : Ar extends NonEmptyArray<infer E> ? Optional.Some<E> : Optional<Ar[number]>;
888
843
  /**
889
844
  * Returns the last element of an array wrapped in an Optional.
890
845
  *
@@ -965,10 +920,7 @@ export declare namespace Arr {
965
920
  * @see {@link at} for accessing elements at specific indices with negative indexing support
966
921
  * @see {@link butLast} for getting all elements except the last
967
922
  */
968
- export function last(array: readonly []): Optional.None;
969
- export function last<Ar extends readonly unknown[], L>(array: readonly [...Ar, L]): Optional.Some<L>;
970
- export function last<E>(array: NonEmptyArray<E>): Optional.Some<E>;
971
- export function last<E>(array: readonly E[]): Optional<E>;
923
+ export const last: <Ar extends readonly unknown[]>(array: Ar) => Ar extends readonly [] ? Optional.None : Ar extends readonly [...unknown[], infer E] ? Optional.Some<E> : Ar extends NonEmptyArray<infer E> ? Optional.Some<E> : Optional<Ar[number]>;
972
924
  /**
973
925
  * Slices an array with automatically clamped start and end indices for safe bounds handling.
974
926
  *
@@ -1052,8 +1004,8 @@ export declare namespace Arr {
1052
1004
  * @see {@link skip} for skipping the first N elements
1053
1005
  * @see {@link takeLast} for taking the last N elements
1054
1006
  */
1055
- export function sliceClamped<E>(array: readonly E[], start: SizeType.ArgArr, end: SizeType.ArgArr): readonly E[];
1056
- export function sliceClamped(start: SizeType.ArgArr, end: SizeType.ArgArr): <E>(array: readonly E[]) => readonly E[];
1007
+ export function sliceClamped<Ar extends readonly unknown[]>(array: Ar, start: ArgArrayIndexWithNegative<Ar>, end: ArgArrayIndexWithNegative<Ar>): readonly Ar[number][];
1008
+ export function sliceClamped(start: SizeType.ArgArrWithNegative, end: SizeType.ArgArrWithNegative): <E>(array: readonly E[]) => readonly E[];
1057
1009
  /**
1058
1010
  * Returns all elements of an array except the first one.
1059
1011
  * @template E The type of the array (can be a tuple for more precise typing).
@@ -1103,12 +1055,8 @@ export declare namespace Arr {
1103
1055
  * console.log(result); // [1, 2, 3]
1104
1056
  * ```
1105
1057
  */
1106
- export function take<Ar extends readonly unknown[], N extends SmallUint>(array: Ar, num: N): List.Take<N, Ar>;
1107
- export function take<N extends SmallUint>(num: N): <Ar extends readonly unknown[]>(array: Ar) => List.Take<N, Ar>;
1108
- export function take<E>(array: NonEmptyArray<E>, num: SizeType.ArgArrPositive): NonEmptyArray<E>;
1109
- export function take(num: SizeType.ArgArrPositive): <E>(array: NonEmptyArray<E>) => NonEmptyArray<E>;
1110
- export function take<E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1111
- export function take(num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1058
+ export function take<Ar extends readonly unknown[], N extends SizeType.ArgArr>(array: Ar, num: N): N extends SmallUint ? List.Take<N, Ar> : N extends SizeType.ArgArrPositive ? Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][] : readonly Ar[number][];
1059
+ export function take<N extends SizeType.ArgArr>(num: N): <Ar extends readonly unknown[]>(array: Ar) => N extends SmallUint ? List.Take<N, Ar> : N extends SizeType.ArgArrPositive ? Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][] : readonly Ar[number][];
1112
1060
  /**
1113
1061
  * Takes the last N elements from an array.
1114
1062
  *
@@ -1132,12 +1080,8 @@ export declare namespace Arr {
1132
1080
  * console.log(result); // [4, 5]
1133
1081
  * ```
1134
1082
  */
1135
- export function takeLast<Ar extends readonly unknown[], N extends SmallUint>(array: Ar, num: N): List.TakeLast<N, Ar>;
1136
- export function takeLast<N extends SmallUint>(num: N): <Ar extends readonly unknown[]>(array: Ar) => List.TakeLast<N, Ar>;
1137
- export function takeLast<E>(array: NonEmptyArray<E>, num: SizeType.ArgArrPositive): NonEmptyArray<E>;
1138
- export function takeLast(num: SizeType.ArgArrPositive): <E>(array: NonEmptyArray<E>) => NonEmptyArray<E>;
1139
- export function takeLast<E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1140
- export function takeLast(num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1083
+ export function takeLast<Ar extends readonly unknown[], N extends SizeType.ArgArr>(array: Ar, num: N): N extends SmallUint ? List.TakeLast<N, Ar> : N extends SizeType.ArgArrPositive ? Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][] : readonly Ar[number][];
1084
+ export function takeLast<N extends SizeType.ArgArr>(num: N): <Ar extends readonly unknown[]>(array: Ar) => N extends SmallUint ? List.TakeLast<N, Ar> : N extends SizeType.ArgArrPositive ? Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][] : readonly Ar[number][];
1141
1085
  /**
1142
1086
  * Skips the first N elements of an array.
1143
1087
  *
@@ -1161,12 +1105,8 @@ export declare namespace Arr {
1161
1105
  * console.log(result); // [3, 4, 5]
1162
1106
  * ```
1163
1107
  */
1164
- export function skip<Ar extends readonly unknown[], N extends SmallUint>(array: Ar, num: N): List.Skip<N, Ar>;
1165
- export function skip<E>(array: NonEmptyArray<E>, num: SizeType.ArgArrPositive): readonly E[];
1166
- export function skip<E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1167
- export function skip<N extends SmallUint>(num: N): <Ar extends readonly unknown[]>(array: Ar) => List.Skip<N, Ar>;
1168
- export function skip(num: SizeType.ArgArrPositive): <E>(array: NonEmptyArray<E>) => readonly E[];
1169
- export function skip(num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1108
+ export function skip<Ar extends readonly unknown[], N extends SizeType.ArgArr>(array: Ar, num: N): N extends SmallUint ? List.Skip<N, Ar> : readonly Ar[number][];
1109
+ export function skip<N extends SizeType.ArgArr>(num: N): <Ar extends readonly unknown[]>(array: Ar) => N extends SmallUint ? List.Skip<N, Ar> : readonly Ar[number][];
1170
1110
  /**
1171
1111
  * Skips the last N elements of an array.
1172
1112
  *
@@ -1190,10 +1130,49 @@ export declare namespace Arr {
1190
1130
  * console.log(result); // [1, 2, 3]
1191
1131
  * ```
1192
1132
  */
1193
- export function skipLast<Ar extends readonly unknown[], N extends SmallUint>(array: Ar, num: N): List.SkipLast<N, Ar>;
1194
- export function skipLast<N extends SmallUint>(num: N): <Ar extends readonly unknown[]>(array: Ar) => List.SkipLast<N, Ar>;
1195
- export function skipLast<E>(array: readonly E[], num: SizeType.ArgArrNonNegative): readonly E[];
1196
- export function skipLast(num: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1133
+ export function skipLast<Ar extends readonly unknown[], N extends SizeType.ArgArr>(array: Ar, num: N): N extends SmallUint ? List.SkipLast<N, Ar> : readonly Ar[number][];
1134
+ export function skipLast<N extends SizeType.ArgArr>(num: N): <Ar extends readonly unknown[]>(array: Ar) => N extends SmallUint ? List.SkipLast<N, Ar> : readonly Ar[number][];
1135
+ /**
1136
+ * Returns a new tuple with the element at the specified index replaced.
1137
+ *
1138
+ * This operation is type-safe with compile-time index validation.
1139
+ * The resulting tuple type reflects that the element at the given index
1140
+ * may be either the new type or the original type.
1141
+ *
1142
+ * @template T - The type of the input tuple
1143
+ * @template N - The type of the new value to set
1144
+ * @param tpl - The input tuple
1145
+ * @param index - The index to update (must be valid for the tuple length)
1146
+ * @param newValue - The new value to place at the index
1147
+ * @returns A new tuple with the updated element
1148
+ *
1149
+ * @example
1150
+ * ```typescript
1151
+ * // Basic usage
1152
+ * const tpl = ['a', 'b', 'c'] as const;
1153
+ * const updated = Arr.set(tpl, 1, 'B'); // readonly ['a', 'B', 'c']
1154
+ *
1155
+ * // Type changes are reflected
1156
+ * const mixed = [1, 'hello', true] as const;
1157
+ * const withNumber = Arr.set(mixed, 1, 42);
1158
+ * // readonly [1, 42 | 'hello', true]
1159
+ *
1160
+ * // Compile-time index validation
1161
+ * const short = [1, 2] as const;
1162
+ * // Arr.set(short, 2, 3); // Error: index 2 is out of bounds
1163
+ *
1164
+ * // Different value types
1165
+ * const nums = [1, 2, 3] as const;
1166
+ * const withString = Arr.set(nums, 0, 'first');
1167
+ * // readonly ['first' | 1, 2, 3]
1168
+ * ```
1169
+ */
1170
+ export function set<const Ar extends readonly unknown[], const V = Ar[number]>(array: Ar, index: ArgArrayIndex<Ar>, newValue: V): IsFixedLengthList<Ar> extends true ? Readonly<{
1171
+ [K in keyof Ar]: Ar[K] | V;
1172
+ }> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number] | V> : readonly (Ar[number] | V)[];
1173
+ export function set<const V>(index: SizeType.ArgArr, newValue: V): <const Ar extends readonly unknown[]>(array: Ar) => IsFixedLengthList<Ar> extends true ? Readonly<{
1174
+ [K in keyof Ar]: Ar[K] | V;
1175
+ }> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number] | V> : readonly (Ar[number] | V)[];
1197
1176
  /**
1198
1177
  * Returns a new array with the element at the specified index updated by a function.
1199
1178
  *
@@ -1215,9 +1194,9 @@ export declare namespace Arr {
1215
1194
  * updater, returns a reusable function that can be applied to arrays.
1216
1195
  *
1217
1196
  * @template E The type of elements in the original array.
1218
- * @template U The type of the value returned by the updater function.
1197
+ * @template V The type of the value returned by the updater function.
1219
1198
  * @param array The input array to update. Can be any readonly array.
1220
- * @param index The index of the element to update. Must be a non-negative {@link SizeType.ArgArrNonNegative}.
1199
+ * @param index The index of the element to update. Must be a non-negative {@link SizeType.ArgArr}.
1221
1200
  * - **Valid range:** `0 <= index < array.length`
1222
1201
  * - **Out of bounds:** Returns original array unchanged
1223
1202
  * - **Negative values:** Not allowed by type system (non-negative constraint)
@@ -1345,11 +1324,15 @@ export declare namespace Arr {
1345
1324
  * ```
1346
1325
  *
1347
1326
  * @see {@link Array.prototype.with} for the native method with different error handling
1348
- * @see {@link SizeType.ArgArrNonNegative} for the index type constraint
1327
+ * @see {@link SizeType.ArgArr} for the index type constraint
1349
1328
  * @see Immutable update patterns for functional programming approaches
1350
1329
  */
1351
- export function toUpdated<E, U>(array: readonly E[], index: SizeType.ArgArrNonNegative, updater: (prev: E) => U): readonly (E | U)[];
1352
- export function toUpdated<E, U>(index: SizeType.ArgArrNonNegative, updater: (prev: E) => U): (array: readonly E[]) => readonly (E | U)[];
1330
+ export function toUpdated<const Ar extends readonly unknown[], const V = Ar[number]>(array: Ar, index: ArgArrayIndex<Ar>, updater: (prev: Ar[number]) => V): IsFixedLengthList<Ar> extends true ? Readonly<{
1331
+ [K in keyof Ar]: Ar[K] | V;
1332
+ }> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number] | V> : readonly (Ar[number] | V)[];
1333
+ export function toUpdated<E, const V = E>(index: SizeType.ArgArr, updater: (prev: E) => V): <const Ar extends readonly E[]>(array: Ar) => IsFixedLengthList<Ar> extends true ? Readonly<{
1334
+ [K in keyof Ar]: Ar[K] | V;
1335
+ }> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number] | V> : readonly (Ar[number] | V)[];
1353
1336
  /**
1354
1337
  * Returns a new array with a new value inserted at the specified index.
1355
1338
  * Index can be out of bounds (e.g., negative or greater than length), `toSpliced` handles this.
@@ -1369,8 +1352,9 @@ export declare namespace Arr {
1369
1352
  * console.log(result); // [99, 1, 2, 3]
1370
1353
  * ```
1371
1354
  */
1372
- export function toInserted<E, const V = E>(array: readonly E[], index: SizeType.ArgArrNonNegative, newValue: V): NonEmptyArray<E | V>;
1373
- export function toInserted<E, const V = E>(index: SizeType.ArgArrNonNegative, newValue: V): (array: readonly E[]) => NonEmptyArray<E | V>;
1355
+ export function toInserted<Ar extends readonly unknown[], const V = Ar[number]>(array: Ar, index: ArgArrayIndexWithNegative<Ar>, newValue: V): IsFixedLengthList<Ar> extends true ? ArrayOfLength<CastToNumber<Increment<Ar['length']>>, Ar[number] | V> : NonEmptyArray<Ar[number] | V>;
1356
+ export function toInserted<const V>(index: SizeType.ArgArrWithNegative, newValue: V): <Ar extends readonly unknown[]>(array: Ar) => IsFixedLengthList<Ar> extends true ? ArrayOfLength<CastToNumber<Increment<Ar['length']>>, Ar[number] | V> : NonEmptyArray<Ar[number] | V>;
1357
+ type CastToNumber<T> = T extends number ? T : never;
1374
1358
  /**
1375
1359
  * Returns a new array with the element at the specified index removed.
1376
1360
  * If index is out of bounds, `toSpliced` handles this (usually by returning a copy).
@@ -1389,8 +1373,8 @@ export declare namespace Arr {
1389
1373
  * console.log(result); // [20, 30]
1390
1374
  * ```
1391
1375
  */
1392
- export function toRemoved<E>(array: readonly E[], index: SizeType.ArgArrNonNegative): readonly E[];
1393
- export function toRemoved(index: SizeType.ArgArrNonNegative): <E>(array: readonly E[]) => readonly E[];
1376
+ export function toRemoved<Ar extends readonly unknown[]>(array: Ar, index: ArgArrayIndexWithNegative<Ar>): readonly Ar[number][];
1377
+ export function toRemoved(index: SizeType.ArgArrWithNegative): <E>(array: readonly E[]) => readonly E[];
1394
1378
  /**
1395
1379
  * Returns a new array with a value added to the end.
1396
1380
  * @template E The type of the input array (can be a tuple).
@@ -1432,29 +1416,75 @@ export declare namespace Arr {
1432
1416
  export function toUnshifted<Ar extends readonly unknown[], const V>(array: Ar, newValue: V): readonly [V, ...Ar];
1433
1417
  export function toUnshifted<const V>(newValue: V): <Ar extends readonly unknown[]>(array: Ar) => readonly [V, ...Ar];
1434
1418
  /**
1435
- * Fills an array with a value (creates a new filled array).
1436
- * @param array The array.
1437
- * @param value The value to fill with.
1438
- * @param start The start index.
1439
- * @param end The end index.
1440
- * @returns A new filled array.
1419
+ * Creates a new array of the same length filled with a specified value.
1420
+ *
1421
+ * This function replaces all elements in the array with the provided value,
1422
+ * maintaining the original array's length and structure. It provides type-safe
1423
+ * array filling with precise return types.
1424
+ *
1425
+ * @template Ar The exact type of the input array.
1426
+ * @template V The type of the fill value.
1427
+ * @param array The array to fill.
1428
+ * @param value The value to fill the array with.
1429
+ * @returns A new array of the same length filled with the specified value:
1430
+ * - For fixed-length arrays: returns `ArrayOfLength<Ar['length'], V>`
1431
+ * - For non-empty arrays: returns `NonEmptyArray<V>`
1432
+ * - For general arrays: returns `readonly V[]`
1433
+ *
1434
+ * @example
1435
+ * ```typescript
1436
+ * // Regular usage
1437
+ * const numbers = [1, 2, 3, 4, 5];
1438
+ * const zeros = Arr.toFilled(numbers, 0); // [0, 0, 0, 0, 0]
1439
+ *
1440
+ * // Curried usage for pipe composition
1441
+ * const fillWithX = Arr.toFilled('X');
1442
+ * const result = pipe(['a', 'b', 'c']).map(fillWithX).value; // ['X', 'X', 'X']
1443
+ * ```
1444
+ *
1445
+ * @see {@link toRangeFilled} for filling only a specific range
1446
+ * @see {@link create} for creating new arrays filled with a value
1447
+ */
1448
+ export function toFilled<Ar extends readonly unknown[], const V>(array: Ar, value: V): IsFixedLengthList<Ar> extends true ? ArrayOfLength<Ar['length'], V> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<V> : readonly V[];
1449
+ export function toFilled<const V>(value: V): <Ar extends readonly unknown[]>(array: Ar) => IsFixedLengthList<Ar> extends true ? ArrayOfLength<Ar['length'], V> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<V> : readonly V[];
1450
+ /**
1451
+ * Creates a new array with a specific range filled with a specified value.
1452
+ *
1453
+ * This function fills only the specified range of indices with the provided value,
1454
+ * leaving other elements unchanged. It provides type-safe range filling with
1455
+ * precise return types.
1456
+ *
1457
+ * @template Ar The exact type of the input array.
1458
+ * @template V The type of the fill value.
1459
+ * @param array The array to fill a range of.
1460
+ * @param value The value to fill the range with.
1461
+ * @param fillRange A tuple containing [start, end] indices for the range to fill.
1462
+ * @returns A new array with the specified range filled:
1463
+ * - For fixed-length arrays: returns `ArrayOfLength<Ar['length'], V | Ar[number]>`
1464
+ * - For non-empty arrays: returns `NonEmptyArray<V | Ar[number]>`
1465
+ * - For general arrays: returns `readonly (V | Ar[number])[]`
1466
+ *
1441
1467
  * @example
1442
1468
  * ```typescript
1443
1469
  * // Regular usage
1444
- * const arr = [1, 2, 3, 4, 5];
1445
- * const result = Arr.toFilled(arr, 0, 1, 4);
1446
- * console.log(result); // [1, 0, 0, 0, 5]
1470
+ * const numbers = [1, 2, 3, 4, 5];
1471
+ * const result = Arr.toRangeFilled(numbers, 0, [1, 4]); // [1, 0, 0, 0, 5]
1447
1472
  *
1448
1473
  * // Curried usage for pipe composition
1449
- * const fillWithZeros = Arr.toFilled(0, 1, 3);
1450
- * const result2 = pipe([1, 2, 3, 4]).map(fillWithZeros).value;
1451
- * console.log(result2); // [1, 0, 0, 4]
1474
+ * const fillMiddleWithX = Arr.toRangeFilled('X', [1, 3]);
1475
+ * const result2 = pipe(['a', 'b', 'c', 'd']).map(fillMiddleWithX).value; // ['a', 'X', 'X', 'd']
1452
1476
  * ```
1477
+ *
1478
+ * @see {@link toFilled} for filling the entire array
1453
1479
  */
1454
- export function toFilled<E>(array: readonly E[], value: E): readonly E[];
1455
- export function toFilled<E>(value: E): (array: readonly E[]) => readonly E[];
1456
- export function toRangeFilled<E>(array: readonly E[], value: E, fillRange: readonly [start: SizeType.ArgArr, end: SizeType.ArgArr]): readonly E[];
1457
- export function toRangeFilled<E>(value: E, fillRange: readonly [start: SizeType.ArgArr, end: SizeType.ArgArr]): (array: readonly E[]) => readonly E[];
1480
+ export function toRangeFilled<Ar extends readonly unknown[], const V>(array: Ar, value: V, fillRange: readonly [
1481
+ start: ArgArrayIndexWithNegative<Ar>,
1482
+ end: ArgArrayIndexWithNegative<Ar>
1483
+ ]): IsFixedLengthList<Ar> extends true ? ArrayOfLength<Ar['length'], V | Ar[number]> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<V | Ar[number]> : readonly (V | Ar[number])[];
1484
+ export function toRangeFilled<const V>(value: V, fillRange: readonly [
1485
+ start: SizeType.ArgArrWithNegative,
1486
+ end: SizeType.ArgArrWithNegative
1487
+ ]): <Ar extends readonly unknown[]>(array: Ar) => IsFixedLengthList<Ar> extends true ? ArrayOfLength<Ar['length'], V | Ar[number]> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<V | Ar[number]> : readonly (V | Ar[number])[];
1458
1488
  /**
1459
1489
  * Safely finds the first element in an array that satisfies a predicate function.
1460
1490
  *
@@ -1492,8 +1522,39 @@ export declare namespace Arr {
1492
1522
  * @see {@link indexOf} for finding elements by equality
1493
1523
  * @see {@link Optional} for working with the returned Optional values
1494
1524
  */
1495
- export function find<E>(array: readonly E[], predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean): Optional<E>;
1525
+ export function find<E, F extends E>(array: readonly E[], predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => value is F): Optional<F>;
1526
+ export function find<Ar extends readonly unknown[]>(array: Ar, predicate: (value: Ar[number], index: ArrayIndex<Ar>, arr: Ar) => boolean): Optional<Ar[number]>;
1496
1527
  export function find<E>(predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean): (array: readonly E[]) => Optional<E>;
1528
+ /**
1529
+ * Returns the last element in an array that satisfies a predicate function.
1530
+ *
1531
+ * This function searches from the end of the array and returns an Optional containing
1532
+ * the first element found that satisfies the predicate, or None if no such element exists.
1533
+ *
1534
+ * @template Ar The exact type of the input array.
1535
+ * @template E The type of elements in the array.
1536
+ * @param array The array to search.
1537
+ * @param predicate A function that tests each element.
1538
+ * @returns An Optional containing the found element, or None if no element satisfies the predicate.
1539
+ *
1540
+ * @example
1541
+ * ```typescript
1542
+ * // Direct usage
1543
+ * const numbers = [1, 2, 3, 4, 5];
1544
+ * const lastEven = Arr.findLast(numbers, n => n % 2 === 0); // Optional.some(4)
1545
+ *
1546
+ * // Curried usage
1547
+ * const isPositive = (n: number) => n > 0;
1548
+ * const findLastPositive = Arr.findLast(isPositive);
1549
+ * const result = findLastPositive([-1, 2, -3, 4]); // Optional.some(4)
1550
+ *
1551
+ * // No match
1552
+ * const noMatch = Arr.findLast([1, 3, 5], n => n % 2 === 0); // Optional.none
1553
+ * ```
1554
+ */
1555
+ export function findLast<E, F extends E>(array: readonly E[], predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => value is F): Optional<F>;
1556
+ export function findLast<Ar extends readonly unknown[]>(array: Ar, predicate: (value: Ar[number], index: ArrayIndex<Ar>, arr: Ar) => boolean): Optional<Ar[number]>;
1557
+ export function findLast<E>(predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean): (array: readonly E[]) => Optional<E>;
1497
1558
  /**
1498
1559
  * Safely finds the index of the first element in an array that satisfies a predicate function.
1499
1560
  *
@@ -1599,8 +1660,100 @@ export declare namespace Arr {
1599
1660
  * @see {@link lastIndexOf} for finding the last occurrence
1600
1661
  * @see {@link Optional} for working with the returned Optional values
1601
1662
  */
1602
- export function findIndex<E>(array: readonly E[], predicate: (value: E, index: SizeType.Arr) => boolean): SizeType.Arr | -1;
1603
- export function findIndex<E>(predicate: (value: E, index: SizeType.Arr) => boolean): (array: readonly E[]) => SizeType.Arr | -1;
1663
+ export function findIndex<Ar extends readonly unknown[]>(array: Ar, predicate: (value: Ar[number], index: ArrayIndex<Ar>, arr: Ar) => boolean): ArrayIndex<Ar> | -1;
1664
+ export function findIndex<E>(predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean): (array: readonly E[]) => SizeType.Arr | -1;
1665
+ /**
1666
+ * Safely finds the index of the last element in an array that satisfies a predicate function.
1667
+ *
1668
+ * This function provides type-safe index searching with no risk of runtime errors. It searches
1669
+ * from the end of the array backwards and returns the index of the last element that matches
1670
+ * the predicate, or -1 if no element is found. The returned index is branded as `SizeType.Arr`
1671
+ * for type safety.
1672
+ *
1673
+ * **Curried Usage:** This function supports currying - when called with only a predicate,
1674
+ * it returns a function that can be applied to arrays, making it ideal for functional composition.
1675
+ *
1676
+ * @template Ar The exact type of the input array, used for precise return type inference.
1677
+ * @template E The type of elements in the array.
1678
+ * @param array The array to search through (when using direct call syntax).
1679
+ * @param predicate A function that tests each element. Called with:
1680
+ * - `value`: The current element being tested
1681
+ * - `index`: The index of the current element (branded as `SizeType.Arr`)
1682
+ * - `arr`: The array being searched
1683
+ * @returns The index of the last matching element as `SizeType.Arr`, or -1 if no element satisfies the predicate.
1684
+ *
1685
+ * @example
1686
+ * ```typescript
1687
+ * // Basic last index finding
1688
+ * const fruits = ['apple', 'banana', 'cherry', 'banana'];
1689
+ * const lastBananaIndex = Arr.findLastIndex(fruits, fruit => fruit === 'banana');
1690
+ * console.log(lastBananaIndex); // 3 - index of last 'banana'
1691
+ *
1692
+ * // Finding with complex conditions
1693
+ * const numbers = [1, 5, 10, 15, 20, 10, 5];
1694
+ * const lastLargeIndex = Arr.findLastIndex(numbers, (value, index) =>
1695
+ * value > 8 && index < 5
1696
+ * );
1697
+ * console.log(lastLargeIndex); // 3 - index of last value > 8 before index 5 (15)
1698
+ *
1699
+ * // Finding objects by property
1700
+ * const users = [
1701
+ * { id: 1, active: true },
1702
+ * { id: 2, active: false },
1703
+ * { id: 3, active: true },
1704
+ * { id: 4, active: false }
1705
+ * ];
1706
+ *
1707
+ * const lastActiveIndex = Arr.findLastIndex(users, user => user.active);
1708
+ * console.log(lastActiveIndex); // 2 - index of last active user
1709
+ *
1710
+ * const lastInactiveIndex = Arr.findLastIndex(users, user => !user.active);
1711
+ * console.log(lastInactiveIndex); // 3 - index of last inactive user
1712
+ *
1713
+ * // Empty array handling
1714
+ * const emptyResult = Arr.findLastIndex([], (x: number) => x > 0); // -1
1715
+ *
1716
+ * // Curried usage for functional composition
1717
+ * const findLastNegativeIndex = Arr.findLastIndex((x: number) => x < 0);
1718
+ * const findLastLongStringIndex = Arr.findLastIndex((s: string) => s.length > 5);
1719
+ *
1720
+ * const datasets = [
1721
+ * [1, 2, -3, 4, -5], // last negative at index 4
1722
+ * [5, 6, 7, 8], // no negative
1723
+ * [-1, 0, 1, -2] // last negative at index 3
1724
+ * ];
1725
+ *
1726
+ * const lastNegativeIndices = datasets.map(findLastNegativeIndex);
1727
+ * // [4, -1, 3]
1728
+ *
1729
+ * // Functional composition
1730
+ * const data = ['short', 'medium', 'very long string', 'tiny', 'another long one'];
1731
+ * const lastLongIndex = Arr.findLastIndex(data, s => s.length > 8);
1732
+ * console.log(lastLongIndex); // 4 - index of 'another long one'
1733
+ *
1734
+ * // Using with pipe
1735
+ * const result = pipe(['a', 'bb', 'ccc', 'bb'])
1736
+ * .map(Arr.findLastIndex((s: string) => s.length === 2))
1737
+ * .value; // 3 (last occurrence of 'bb')
1738
+ *
1739
+ * // Comparing with findIndex
1740
+ * const values = [1, 2, 3, 2, 4];
1741
+ * const firstTwo = Arr.findIndex(values, x => x === 2); // 1
1742
+ * const lastTwo = Arr.findLastIndex(values, x => x === 2); // 3
1743
+ *
1744
+ * // Type safety with tuples
1745
+ * const tuple = [10, 20, 30, 20] as const;
1746
+ * const lastTwentyIndex = Arr.findLastIndex(tuple, x => x === 20);
1747
+ * // Type: ArrayIndex<readonly [10, 20, 30, 20]> | -1
1748
+ * // Value: 3
1749
+ * ```
1750
+ *
1751
+ * @see {@link findLast} for finding the element instead of its index
1752
+ * @see {@link findIndex} for finding the first occurrence
1753
+ * @see {@link lastIndexOf} for finding elements by equality (not predicate)
1754
+ */
1755
+ export function findLastIndex<Ar extends readonly unknown[]>(array: Ar, predicate: (value: Ar[number], index: ArrayIndex<Ar>, arr: Ar) => boolean): ArrayIndex<Ar> | -1;
1756
+ export function findLastIndex<E>(predicate: (value: E, index: SizeType.Arr, arr: readonly E[]) => boolean): (array: readonly E[]) => SizeType.Arr | -1;
1604
1757
  /**
1605
1758
  * Gets the index of a value in an array.
1606
1759
  * @param array The array to search.
@@ -1622,10 +1775,10 @@ export declare namespace Arr {
1622
1775
  * console.log(Optional.unwrapOr(result2, -1)); // 1
1623
1776
  * ```
1624
1777
  */
1625
- export function indexOf<E>(array: readonly E[], searchElement: E): SizeType.Arr | -1;
1778
+ export function indexOf<Ar extends readonly unknown[]>(array: Ar, searchElement: Ar[number]): ArrayIndex<Ar> | -1;
1626
1779
  export function indexOf<E>(searchElement: E): (array: readonly E[]) => SizeType.Arr | -1;
1627
- export function indexOfFrom<E>(array: readonly E[], searchElement: E, fromIndex: SizeType.ArgArr): SizeType.Arr | -1;
1628
- export function indexOfFrom<E>(searchElement: E, fromIndex: SizeType.ArgArr): (array: readonly E[]) => SizeType.Arr | -1;
1780
+ export function indexOfFrom<Ar extends readonly unknown[]>(array: Ar, searchElement: Ar[number], fromIndex: ArgArrayIndexWithNegative<Ar>): ArrayIndex<Ar> | -1;
1781
+ export function indexOfFrom<E>(searchElement: E, fromIndex: SizeType.ArgArrWithNegative): (array: readonly E[]) => SizeType.Arr | -1;
1629
1782
  /**
1630
1783
  * Gets the last index of a value in an array.
1631
1784
  * @param array The array to search.
@@ -1647,10 +1800,85 @@ export declare namespace Arr {
1647
1800
  * console.log(Optional.unwrapOr(result2, -1)); // 3
1648
1801
  * ```
1649
1802
  */
1650
- export function lastIndexOf<E>(array: readonly E[], searchElement: E): SizeType.Arr | -1;
1803
+ export function lastIndexOf<Ar extends readonly unknown[]>(array: Ar, searchElement: Ar[number]): ArrayIndex<Ar> | -1;
1651
1804
  export function lastIndexOf<E>(searchElement: E): (array: readonly E[]) => SizeType.Arr | -1;
1652
- export function lastIndexOfFrom<E>(array: readonly E[], searchElement: E, fromIndex: SizeType.ArgArr): SizeType.Arr | -1;
1653
- export function lastIndexOfFrom<E>(searchElement: E, fromIndex: SizeType.ArgArr): (array: readonly E[]) => SizeType.Arr | -1;
1805
+ export function lastIndexOfFrom<Ar extends readonly unknown[]>(array: Ar, searchElement: Ar[number], fromIndex: ArgArrayIndexWithNegative<Ar>): ArrayIndex<Ar> | -1;
1806
+ export function lastIndexOfFrom<E>(searchElement: E, fromIndex: SizeType.ArgArrWithNegative): (array: readonly E[]) => SizeType.Arr | -1;
1807
+ /**
1808
+ * Tests whether all elements in an array pass a test implemented by a predicate function.
1809
+ *
1810
+ * This function returns `true` if all elements satisfy the predicate, `false` otherwise.
1811
+ * For empty arrays, it returns `true` (vacuous truth).
1812
+ * Supports type guard predicates for type narrowing of the entire array.
1813
+ *
1814
+ * @template Ar The exact type of the input array.
1815
+ * @template E The type of elements in the array.
1816
+ * @template S The narrowed type when using type guard predicates.
1817
+ * @param array The array to test.
1818
+ * @param predicate A function that tests each element.
1819
+ * @returns `true` if all elements pass the test, `false` otherwise.
1820
+ *
1821
+ * @example
1822
+ * ```typescript
1823
+ * // Direct usage
1824
+ * const numbers = [2, 4, 6, 8];
1825
+ * const allEven = Arr.every(numbers, n => n % 2 === 0); // true
1826
+ *
1827
+ * // Type guard usage - narrows entire array type
1828
+ * const mixed: (string | number)[] = ['hello', 'world'];
1829
+ * if (Arr.every(mixed, (x): x is string => typeof x === 'string')) {
1830
+ * // TypeScript knows mixed is string[] here
1831
+ * console.log(mixed.map(s => s.toUpperCase()));
1832
+ * }
1833
+ *
1834
+ * // Curried usage with type guards
1835
+ * const isString = (x: unknown): x is string => typeof x === 'string';
1836
+ * const allStrings = Arr.every(isString);
1837
+ * const data: unknown[] = ['a', 'b', 'c'];
1838
+ * if (allStrings(data)) {
1839
+ * // TypeScript knows data is string[] here
1840
+ * console.log(data.join(''));
1841
+ * }
1842
+ *
1843
+ * // Empty array
1844
+ * const empty: number[] = [];
1845
+ * const result2 = Arr.every(empty, n => n > 0); // true
1846
+ * ```
1847
+ */
1848
+ export function every<E, S extends E>(array: readonly E[], predicate: (a: E, index: SizeType.Arr) => a is S): array is readonly S[];
1849
+ export function every<E, S extends E>(predicate: (a: E, index: SizeType.Arr) => a is S): (array: readonly E[]) => array is readonly S[];
1850
+ export function every<Ar extends readonly unknown[]>(array: Ar, predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean): boolean;
1851
+ export function every<E>(predicate: (a: E, index: SizeType.Arr) => boolean): (array: readonly E[]) => boolean;
1852
+ /**
1853
+ * Tests whether at least one element in an array passes a test implemented by a predicate function.
1854
+ *
1855
+ * This function returns `true` if at least one element satisfies the predicate, `false` otherwise.
1856
+ * For empty arrays, it returns `false`.
1857
+ *
1858
+ * @template Ar The exact type of the input array.
1859
+ * @template E The type of elements in the array.
1860
+ * @param array The array to test.
1861
+ * @param predicate A function that tests each element.
1862
+ * @returns `true` if at least one element passes the test, `false` otherwise.
1863
+ *
1864
+ * @example
1865
+ * ```typescript
1866
+ * // Direct usage
1867
+ * const numbers = [1, 3, 5, 8];
1868
+ * const hasEven = Arr.some(numbers, n => n % 2 === 0); // true
1869
+ *
1870
+ * // Curried usage
1871
+ * const isNegative = (n: number) => n < 0;
1872
+ * const hasNegative = Arr.some(isNegative);
1873
+ * const result = hasNegative([1, 2, -3]); // true
1874
+ *
1875
+ * // Empty array
1876
+ * const empty: number[] = [];
1877
+ * const result2 = Arr.some(empty, n => n > 0); // false
1878
+ * ```
1879
+ */
1880
+ export function some<Ar extends readonly unknown[]>(array: Ar, predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean): boolean;
1881
+ export function some<E>(predicate: (a: E, index: SizeType.Arr) => boolean): (array: readonly E[]) => boolean;
1654
1882
  /**
1655
1883
  * Applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
1656
1884
  * This is an alias for `Array.prototype.reduce`.
@@ -1666,7 +1894,7 @@ export declare namespace Arr {
1666
1894
  * Arr.foldl(['a', 'b', 'c'], (acc, str) => acc + str.toUpperCase(), ''); // 'ABC'
1667
1895
  * ```
1668
1896
  */
1669
- export function foldl<E, P>(array: readonly E[], callbackfn: (previousValue: P, currentValue: E, currentIndex: SizeType.Arr) => P, initialValue: P): P;
1897
+ export function foldl<Ar extends readonly unknown[], P>(array: Ar, callbackfn: (previousValue: P, currentValue: Ar[number], currentIndex: ArrayIndex<Ar>) => P, initialValue: P): P;
1670
1898
  export function foldl<E, P>(callbackfn: (previousValue: P, currentValue: E, currentIndex: SizeType.Arr) => P, initialValue: P): (array: readonly E[]) => P;
1671
1899
  /**
1672
1900
  * Applies a function against an accumulator and each element in the array (from right to left) to reduce it to a single value.
@@ -1688,7 +1916,7 @@ export declare namespace Arr {
1688
1916
  * console.log(result); // "abc"
1689
1917
  * ```
1690
1918
  */
1691
- export function foldr<E, P>(array: readonly E[], callbackfn: (previousValue: P, currentValue: E, currentIndex: SizeType.Arr) => P, initialValue: P): P;
1919
+ export function foldr<Ar extends readonly unknown[], P>(array: Ar, callbackfn: (previousValue: P, currentValue: Ar[number], currentIndex: ArrayIndex<Ar>) => P, initialValue: P): P;
1692
1920
  export function foldr<E, P>(callbackfn: (previousValue: P, currentValue: E, currentIndex: SizeType.Arr) => P, initialValue: P): (array: readonly E[]) => P;
1693
1921
  /**
1694
1922
  * Finds the minimum value in an array.
@@ -1703,10 +1931,8 @@ export declare namespace Arr {
1703
1931
  * Arr.min([]); // Optional.none
1704
1932
  * ```
1705
1933
  */
1706
- export function min<E extends number>(array: NonEmptyArray<E>, comparator?: (x: E, y: E) => number): Optional.Some<E>;
1707
- export function min<E extends number>(array: readonly E[], comparator?: (x: E, y: E) => number): Optional<E>;
1708
- export function min<E>(array: NonEmptyArray<E>, comparator: (x: E, y: E) => number): Optional.Some<E>;
1709
- export function min<E>(array: readonly E[], comparator: (x: E, y: E) => number): Optional<E>;
1934
+ export function min<Ar extends readonly number[]>(array: Ar, comparator?: (x: Ar[number], y: Ar[number]) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1935
+ export function min<Ar extends readonly unknown[]>(array: Ar, comparator: (x: Ar[number], y: Ar[number]) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1710
1936
  /**
1711
1937
  * Finds the maximum value in an array.
1712
1938
  *
@@ -1725,10 +1951,8 @@ export declare namespace Arr {
1725
1951
  * Arr.max([]); // Optional.none
1726
1952
  * ```
1727
1953
  */
1728
- export function max<E extends number>(array: NonEmptyArray<E>, comparator?: (x: E, y: E) => number): Optional.Some<E>;
1729
- export function max<E extends number>(array: readonly E[], comparator?: (x: E, y: E) => number): Optional<E>;
1730
- export function max<E>(array: NonEmptyArray<E>, comparator: (x: E, y: E) => number): Optional.Some<E>;
1731
- export function max<E>(array: readonly E[], comparator: (x: E, y: E) => number): Optional<E>;
1954
+ export function max<Ar extends readonly number[]>(array: Ar, comparator?: (x: Ar[number], y: Ar[number]) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1955
+ export function max<Ar extends readonly unknown[]>(array: Ar, comparator: (x: Ar[number], y: Ar[number]) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1732
1956
  /**
1733
1957
  * Finds the element with the minimum value according to a mapped numeric value.
1734
1958
  *
@@ -1749,10 +1973,8 @@ export declare namespace Arr {
1749
1973
  * Arr.minBy([], p => p.age); // Optional.none
1750
1974
  * ```
1751
1975
  */
1752
- export function minBy<E>(array: NonEmptyArray<E>, comparatorValueMapper: (value: E) => number): Optional.Some<E>;
1753
- export function minBy<E>(array: readonly E[], comparatorValueMapper: (value: E) => number): Optional<E>;
1754
- export function minBy<E, V>(array: NonEmptyArray<E>, comparatorValueMapper: (value: E) => V, comparator: (x: V, y: V) => number): Optional.Some<E>;
1755
- export function minBy<E, V>(array: readonly E[], comparatorValueMapper: (value: E) => V, comparator: (x: V, y: V) => number): Optional<E>;
1976
+ export function minBy<Ar extends readonly unknown[]>(array: Ar, comparatorValueMapper: (value: Ar[number]) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1977
+ export function minBy<Ar extends readonly unknown[], V>(array: Ar, comparatorValueMapper: (value: Ar[number]) => V, comparator: (x: V, y: V) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1756
1978
  /**
1757
1979
  * Finds the element with the maximum value according to a mapped numeric value.
1758
1980
  *
@@ -1773,10 +1995,8 @@ export declare namespace Arr {
1773
1995
  * Arr.maxBy([], p => p.age); // Optional.none
1774
1996
  * ```
1775
1997
  */
1776
- export function maxBy<E>(array: NonEmptyArray<E>, comparatorValueMapper: (value: E) => number): Optional.Some<E>;
1777
- export function maxBy<E>(array: readonly E[], comparatorValueMapper: (value: E) => number): Optional<E>;
1778
- export function maxBy<E, V>(array: NonEmptyArray<E>, comparatorValueMapper: (value: E) => V, comparator: (x: V, y: V) => number): Optional.Some<E>;
1779
- export function maxBy<E, V>(array: readonly E[], comparatorValueMapper: (value: E) => V, comparator: (x: V, y: V) => number): Optional<E>;
1998
+ export function maxBy<Ar extends readonly unknown[]>(array: Ar, comparatorValueMapper: (value: Ar[number]) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1999
+ export function maxBy<Ar extends readonly unknown[], V>(array: Ar, comparatorValueMapper: (value: Ar[number]) => V, comparator: (x: V, y: V) => number): Ar extends NonEmptyArray<unknown> ? Optional.Some<Ar[number]> : Optional<Ar[number]>;
1780
2000
  /**
1781
2001
  * Counts the number of elements in an array that satisfy a predicate.
1782
2002
  * @template E The type of elements in the array.
@@ -1794,7 +2014,7 @@ export declare namespace Arr {
1794
2014
  * console.log(result); // 3
1795
2015
  * ```
1796
2016
  */
1797
- export function count<E>(array: readonly E[], predicate: (value: E, index: SizeType.Arr) => boolean): SizeType.Arr;
2017
+ export function count<Ar extends readonly unknown[]>(array: Ar, predicate: (value: Ar[number], index: ArrayIndex<Ar>) => boolean): SizeType.Arr;
1798
2018
  export function count<E>(predicate: (value: E, index: SizeType.Arr) => boolean): (array: readonly E[]) => SizeType.Arr;
1799
2019
  /**
1800
2020
  * Groups elements of an array by a key derived from each element and counts the elements in each group.
@@ -1816,7 +2036,7 @@ export declare namespace Arr {
1816
2036
  * // IMap { 'a' => 2, 'b' => 1 }
1817
2037
  * ```
1818
2038
  */
1819
- export function countBy<E, G extends MapSetKeyType>(array: readonly E[], grouper: (value: E, index: SizeType.Arr) => G): IMap<G, SizeType.Arr>;
2039
+ export function countBy<Ar extends readonly unknown[], G extends MapSetKeyType>(array: Ar, grouper: (value: Ar[number], index: ArrayIndex<Ar>) => G): IMap<G, ArrayIndex<Ar>>;
1820
2040
  export function countBy<E, G extends MapSetKeyType>(grouper: (value: E, index: SizeType.Arr) => G): (array: readonly E[]) => IMap<G, SizeType.Arr>;
1821
2041
  /**
1822
2042
  * Calculates the sum of numbers in an array.
@@ -1873,6 +2093,87 @@ export declare namespace Arr {
1873
2093
  * ```
1874
2094
  */
1875
2095
  export const zip: <Ar1 extends readonly unknown[], Ar2 extends readonly unknown[]>(array1: Ar1, array2: Ar2) => List.Zip<Ar1, Ar2>;
2096
+ /**
2097
+ * Creates a new tuple by transforming each element with a mapping function.
2098
+ *
2099
+ * Preserves the tuple's length while allowing element type transformation.
2100
+ * The resulting tuple has the same structure but with transformed element types.
2101
+ *
2102
+ * @template T - The type of the input tuple
2103
+ * @template B - The type that elements will be transformed to
2104
+ * @param array - The input tuple
2105
+ * @param mapFn - Function that transforms each element (receives element and index)
2106
+ * @returns A new tuple with transformed elements, preserving the original length
2107
+ *
2108
+ * @example
2109
+ * ```typescript
2110
+ * // Basic transformation
2111
+ * const nums = [1, 2, 3] as const;
2112
+ * const doubled = Arr.map(nums, (x) => x * 2); // readonly [2, 4, 6]
2113
+ * const strings = Arr.map(nums, (x) => String(x)); // readonly ['1', '2', '3']
2114
+ *
2115
+ * // With index
2116
+ * const indexed = Arr.map(nums, (x, i) => `${i}:${x}`);
2117
+ * // readonly ['0:1', '1:2', '2:3']
2118
+ *
2119
+ * // Mixed type tuples
2120
+ * const mixed = [1, 'hello', true] as const;
2121
+ * const descriptions = Arr.map(mixed, (x) => `Value: ${x}`);
2122
+ * // readonly ['Value: 1', 'Value: hello', 'Value: true']
2123
+ * ```
2124
+ */
2125
+ export function map<const Ar extends readonly unknown[], B>(array: Ar, mapFn: (a: Ar[number], index: ArrayIndex<Ar>) => B): Readonly<{
2126
+ [K in keyof Ar]: B;
2127
+ }>;
2128
+ export function map<A, B>(mapFn: (a: A, index: SizeType.Arr) => B): <Ar extends readonly A[]>(array: Ar) => Readonly<{
2129
+ [K in keyof Ar]: B;
2130
+ }>;
2131
+ /**
2132
+ * Filters an array based on a predicate function.
2133
+ *
2134
+ * This function returns a new array containing only the elements that satisfy the predicate.
2135
+ * It provides both direct usage and curried versions for functional composition.
2136
+ * Supports type guard predicates for type narrowing.
2137
+ *
2138
+ * @template Ar The exact type of the input array, used for precise return type inference.
2139
+ * @template E The type of elements in the array.
2140
+ * @template S The narrowed type when using type guard predicates.
2141
+ * @param array The array to filter.
2142
+ * @param predicate A function that tests each element. Returns `true` to keep the element, `false` to filter it out.
2143
+ * @returns A new array containing only the elements that satisfy the predicate.
2144
+ *
2145
+ * @example
2146
+ * ```typescript
2147
+ * // Direct usage
2148
+ * const numbers = [1, 2, 3, 4, 5];
2149
+ * const evens = Arr.filter(numbers, n => n % 2 === 0); // [2, 4]
2150
+ *
2151
+ * // Type guard usage
2152
+ * const mixed: (string | number | null)[] = ['hello', 42, null, 'world'];
2153
+ * const strings = Arr.filter(mixed, (x): x is string => typeof x === 'string'); // string[]
2154
+ * const notNull = Arr.filter(mixed, (x): x is NonNullable<typeof x> => x != null); // (string | number)[]
2155
+ *
2156
+ * // Curried usage with type guards
2157
+ * const isString = (x: unknown): x is string => typeof x === 'string';
2158
+ * const filterStrings = Arr.filter(isString);
2159
+ * const result = filterStrings(['a', 1, 'b', 2]); // string[]
2160
+ *
2161
+ * // Functional composition
2162
+ * const processNumbers = pipe(
2163
+ * Arr.filter((n: number) => n > 0),
2164
+ * Arr.map(n => n * 2)
2165
+ * );
2166
+ * ```
2167
+ *
2168
+ * @see {@link filterNot} for filtering with negated predicate
2169
+ * @see {@link every} for testing if all elements satisfy a predicate
2170
+ * @see {@link some} for testing if any elements satisfy a predicate
2171
+ * @see {@link find} for finding the first element that satisfies a predicate
2172
+ */
2173
+ export function filter<Ar extends readonly unknown[], S extends Ar[number]>(array: Ar, predicate: (a: Ar[number], index: ArrayIndex<Ar>) => a is S): readonly S[];
2174
+ export function filter<E, S extends E>(predicate: (a: E, index: SizeType.Arr) => a is S): (array: readonly E[]) => readonly S[];
2175
+ export function filter<Ar extends readonly unknown[]>(array: Ar, predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean): readonly Ar[number][];
2176
+ export function filter<E>(predicate: (a: E, index: SizeType.Arr) => boolean): (array: readonly E[]) => readonly E[];
1876
2177
  /**
1877
2178
  * Filters an array by excluding elements for which the predicate returns true.
1878
2179
  * This is the opposite of `Array.prototype.filter`.
@@ -1891,8 +2192,68 @@ export declare namespace Arr {
1891
2192
  * console.log(result); // [1, 3, 5]
1892
2193
  * ```
1893
2194
  */
1894
- export function filterNot<E>(array: readonly E[], predicate: (a: E, index: SizeType.Arr) => boolean): readonly E[];
2195
+ export function filterNot<Ar extends readonly unknown[]>(array: Ar, predicate: (a: Ar[number], index: ArrayIndex<Ar>) => boolean): readonly Ar[number][];
1895
2196
  export function filterNot<E>(predicate: (a: E, index: SizeType.Arr) => boolean): (array: readonly E[]) => readonly E[];
2197
+ /**
2198
+ * Creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.
2199
+ *
2200
+ * This function flattens nested arrays to the specified depth level.
2201
+ * A depth of 1 flattens one level, Number.POSITIVE_INFINITY flattens all levels.
2202
+ *
2203
+ * @template Ar The exact type of the input array.
2204
+ * @template D The depth of flattening.
2205
+ * @param array The array to flatten.
2206
+ * @param depth The depth level specifying how deep a nested array structure should be flattened.
2207
+ * @returns A new array with the sub-array elements concatenated.
2208
+ *
2209
+ * @example
2210
+ * ```typescript
2211
+ * // Direct usage
2212
+ * const nested = [1, [2, [3, 4]], 5];
2213
+ * const flat1 = Arr.flat(nested, 1); // [1, 2, [3, 4], 5]
2214
+ * const flat2 = Arr.flat(nested, 2); // [1, 2, 3, 4, 5]
2215
+ *
2216
+ * // Curried usage
2217
+ * const flattenOnceLevel = Arr.flat(1);
2218
+ * const result = flattenOnceLevel([[1, 2], [3, 4]]); // [1, 2, 3, 4]
2219
+ *
2220
+ * // Flatten all levels
2221
+ * const deepNested = [1, [2, [3, [4, 5]]]];
2222
+ * const allFlat = Arr.flat(deepNested, SafeUint.MAX_VALUE); // [1, 2, 3, 4, 5]
2223
+ * ```
2224
+ */
2225
+ export function flat<Ar extends readonly unknown[], D extends SafeUintWithSmallInt = 1>(array: Ar, depth?: D): readonly FlatArray<Ar, D>[];
2226
+ export function flat<D extends SafeUintWithSmallInt = 1>(depth?: number): <Ar extends readonly unknown[]>(array: Ar) => readonly FlatArray<Ar, D>[];
2227
+ /**
2228
+ * Creates a new array with all sub-array elements concatenated into it recursively up to the specified depth,
2229
+ * after first mapping each element using a mapping function.
2230
+ *
2231
+ * This function is equivalent to calling `map` followed by `flat` with depth 1.
2232
+ *
2233
+ * @template Ar The exact type of the input array.
2234
+ * @template E The type of elements in the array.
2235
+ * @template B The type of elements returned by the mapping function.
2236
+ * @param array The array to map and flatten.
2237
+ * @param mapFn A function that produces new elements for the new array.
2238
+ * @returns A new array with mapped elements flattened.
2239
+ *
2240
+ * @example
2241
+ * ```typescript
2242
+ * // Direct usage
2243
+ * const words = ['hello', 'world'];
2244
+ * const chars = Arr.flatMap(words, word => word.split('')); // ['h','e','l','l','o','w','o','r','l','d']
2245
+ *
2246
+ * // Curried usage
2247
+ * const splitWords = Arr.flatMap((word: string) => word.split(''));
2248
+ * const result = splitWords(['foo', 'bar']); // ['f','o','o','b','a','r']
2249
+ *
2250
+ * // With numbers
2251
+ * const numbers = [1, 2, 3];
2252
+ * const doubled = Arr.flatMap(numbers, n => [n, n * 2]); // [1, 2, 2, 4, 3, 6]
2253
+ * ```
2254
+ */
2255
+ export function flatMap<const Ar extends readonly unknown[], B>(array: Ar, mapFn: (a: Ar[number], index: ArrayIndex<Ar>) => readonly B[]): readonly B[];
2256
+ export function flatMap<A, B>(mapFn: (a: A, index: SizeType.Arr) => readonly B[]): (array: readonly A[]) => readonly B[];
1896
2257
  /**
1897
2258
  * Concatenates two arrays.
1898
2259
  * @template E1 The type of the first array (can be a tuple).
@@ -1925,6 +2286,53 @@ export declare namespace Arr {
1925
2286
  */
1926
2287
  export function partition<N extends WithSmallInt<PositiveInt & SizeType.Arr>, E>(array: readonly E[], chunkSize: N): readonly (readonly E[])[];
1927
2288
  export function partition<N extends WithSmallInt<PositiveInt & SizeType.Arr>>(chunkSize: N): <E>(array: readonly E[]) => readonly (readonly E[])[];
2289
+ /**
2290
+ * Reverses a tuple, preserving element types in their new positions.
2291
+ *
2292
+ * The type system precisely tracks the reversal, so the returned tuple
2293
+ * has its element types in the exact reverse order. This is more precise
2294
+ * than array reversal which loses positional type information.
2295
+ *
2296
+ * @template T - The tuple type to reverse
2297
+ * @param array - The input tuple
2298
+ * @returns A new tuple with elements in reverse order and precise typing
2299
+ *
2300
+ * @example
2301
+ * ```typescript
2302
+ * // Basic reversal
2303
+ * const nums = [1, 2, 3] as const;
2304
+ * const reversed = Arr.toReversed(nums); // readonly [3, 2, 1]
2305
+ *
2306
+ * // Mixed types preserved in reverse positions
2307
+ * const mixed = [1, 'hello', true, null] as const;
2308
+ * const revMixed = Arr.toReversed(mixed);
2309
+ * // readonly [null, true, 'hello', 1]
2310
+ *
2311
+ * // Empty and single-element tuples
2312
+ * const empty = [] as const;
2313
+ * const revEmpty = Arr.toReversed(empty); // readonly []
2314
+ * const single = [42] as const;
2315
+ * const revSingle = Arr.toReversed(single); // readonly [42]
2316
+ * ```
2317
+ */
2318
+ export const toReversed: <const Ar extends readonly unknown[]>(array: Ar) => List.Reverse<Ar>;
2319
+ /**
2320
+ * Sorts an array by a value derived from its elements, using a numeric mapping.
2321
+ * @template E The type of elements in the array.
2322
+ * @param array The input array.
2323
+ * @param comparatorValueMapper A function `(value: A) => number` that maps an element to a number for comparison.
2324
+ * @param comparator An optional custom comparator function `(x: number, y: number) => number` for the mapped numbers. Defaults to ascending sort (x - y).
2325
+ * @returns A new array sorted by the mapped values.
2326
+ * @example
2327
+ * ```ts
2328
+ * const items = [{ name: 'Eve', score: 70 }, { name: 'Adam', score: 90 }, { name: 'Bob', score: 80 }];
2329
+ * Arr.toSortedBy(items, item => item.score);
2330
+ * // [{ name: 'Eve', score: 70 }, { name: 'Bob', score: 80 }, { name: 'Adam', score: 90 }]
2331
+ * Arr.toSortedBy(items, item => item.score, (a, b) => b - a); // Sort descending
2332
+ * // [{ name: 'Adam', score: 90 }, { name: 'Bob', score: 80 }, { name: 'Eve', score: 70 }]
2333
+ * ```
2334
+ */
2335
+ export const toSorted: <Ar extends readonly unknown[]>(...[array, comparator]: Ar extends readonly number[] ? readonly [array: Ar, comparator?: (x: Ar[number], y: Ar[number]) => number] : readonly [array: Ar, comparator: (x: Ar[number], y: Ar[number]) => number]) => IsFixedLengthList<Ar> extends true ? ArrayOfLength<Ar["length"], Ar[number]> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][];
1928
2336
  /**
1929
2337
  * Sorts an array by a value derived from its elements, using a numeric mapping.
1930
2338
  * @template E The type of elements in the array.
@@ -1941,8 +2349,8 @@ export declare namespace Arr {
1941
2349
  * // [{ name: 'Adam', score: 90 }, { name: 'Bob', score: 80 }, { name: 'Eve', score: 70 }]
1942
2350
  * ```
1943
2351
  */
1944
- export function toSortedBy<E>(array: readonly E[], comparatorValueMapper: (value: E) => number, comparator?: (x: number, y: number) => number): readonly E[];
1945
- export function toSortedBy<E, const V>(array: readonly E[], comparatorValueMapper: (value: E) => V, comparator: (x: V, y: V) => number): readonly E[];
2352
+ export function toSortedBy<Ar extends readonly unknown[]>(array: Ar, comparatorValueMapper: (value: Ar[number]) => number, comparator?: (x: number, y: number) => number): IsFixedLengthList<Ar> extends true ? ArrayOfLength<Ar['length'], Ar[number]> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][];
2353
+ export function toSortedBy<Ar extends readonly unknown[], const V>(array: Ar, comparatorValueMapper: (value: Ar[number]) => V, comparator: (x: V, y: V) => number): IsFixedLengthList<Ar> extends true ? ArrayOfLength<Ar['length'], Ar[number]> : Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][];
1946
2354
  /**
1947
2355
  * Returns an array of successively reduced values from an array, starting with an initial value.
1948
2356
  *
@@ -2000,8 +2408,8 @@ export declare namespace Arr {
2000
2408
  *
2001
2409
  * // Running maximum
2002
2410
  * const temperatures = [20, 25, 18, 30, 22];
2003
- * const runningMax = Arr.scan(temperatures, (max, temp) => Math.max(max, temp), -Infinity);
2004
- * // [-Infinity, 20, 25, 25, 30, 30]
2411
+ * const runningMax = Arr.scan(temperatures, (max, temp) => Math.max(max, temp), Number.NEGATIVE_INFINITY);
2412
+ * // [Number.NEGATIVE_INFINITY, 20, 25, 25, 30, 30]
2005
2413
  *
2006
2414
  * // Building strings incrementally
2007
2415
  * const words = ['Hello', 'beautiful', 'world'];
@@ -2099,7 +2507,7 @@ export declare namespace Arr {
2099
2507
  * @see {@link SizeType.Arr} for the index parameter type
2100
2508
  * @see Array.prototype.reduce for the standard reduce function
2101
2509
  */
2102
- export function scan<E, S>(array: readonly E[], reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S, init: S): NonEmptyArray<S>;
2510
+ export function scan<Ar extends readonly unknown[], S>(array: Ar, reducer: (accumulator: S, currentValue: Ar[number], currentIndex: ArrayIndex<Ar>) => S, init: S): NonEmptyArray<S>;
2103
2511
  export function scan<E, S>(reducer: (accumulator: S, currentValue: E, currentIndex: SizeType.Arr) => S, init: S): (array: readonly E[]) => NonEmptyArray<S>;
2104
2512
  /**
2105
2513
  * Groups elements of an array by a key derived from each element, returning an immutable {@link IMap}.
@@ -2250,7 +2658,7 @@ export declare namespace Arr {
2250
2658
  * @see {@link IMap.map} for transforming grouped data
2251
2659
  * @see {@link Optional} for handling potentially missing groups
2252
2660
  */
2253
- export function groupBy<E, G extends MapSetKeyType>(array: readonly E[], grouper: (value: E, index: SizeType.Arr) => G): IMap<G, readonly E[]>;
2661
+ export function groupBy<Ar extends readonly unknown[], G extends MapSetKeyType>(array: Ar, grouper: (value: Ar[number], index: ArrayIndex<Ar>) => G): IMap<G, readonly Ar[number][]>;
2254
2662
  export function groupBy<E, G extends MapSetKeyType>(grouper: (value: E, index: SizeType.Arr) => G): (array: readonly E[]) => IMap<G, readonly E[]>;
2255
2663
  /**
2256
2664
  * Creates a new array with unique elements from the input array. Order is preserved from the first occurrence.
@@ -2263,7 +2671,7 @@ export declare namespace Arr {
2263
2671
  * Arr.uniq([1, 2, 2, 3, 1, 4]); // [1, 2, 3, 4]
2264
2672
  * ```
2265
2673
  */
2266
- export const uniq: <P extends Primitive>(array: readonly P[]) => readonly P[];
2674
+ export const uniq: <Ar extends readonly Primitive[]>(array: Ar) => Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][];
2267
2675
  /**
2268
2676
  * Creates a new array with unique elements from the input array, based on the values returned by `mapFn`.
2269
2677
  *
@@ -2285,8 +2693,7 @@ export declare namespace Arr {
2285
2693
  * Arr.uniqBy(users, user => user.id); // [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
2286
2694
  * ```
2287
2695
  */
2288
- export function uniqBy<E, P extends Primitive>(array: NonEmptyArray<E>, mapFn: (value: E) => P): NonEmptyArray<E>;
2289
- export function uniqBy<E, P extends Primitive>(array: readonly E[], mapFn: (value: E) => P): readonly E[];
2696
+ export const uniqBy: <Ar extends readonly unknown[], P extends Primitive>(array: Ar, mapFn: (value: Ar[number]) => P) => Ar extends NonEmptyArray<unknown> ? NonEmptyArray<Ar[number]> : readonly Ar[number][];
2290
2697
  /**
2291
2698
  * Checks if two arrays are equal by performing a shallow comparison of their elements.
2292
2699
  * @template E The type of elements in the arrays.
@@ -2393,11 +2800,84 @@ export declare namespace Arr {
2393
2800
  * ```
2394
2801
  */
2395
2802
  export const sortedNumSetDifference: <E extends number>(sortedList1: readonly E[], sortedList2: readonly E[]) => readonly E[];
2803
+ /**
2804
+ * Returns an iterable of key-value pairs for every entry in the array.
2805
+ *
2806
+ * This function returns an array where each element is a tuple containing the index and value.
2807
+ * The indices are branded as `SizeType.Arr` for type safety.
2808
+ *
2809
+ * @template Ar The exact type of the input array.
2810
+ * @param array The array to get entries from.
2811
+ * @returns An array of `[index, value]` pairs.
2812
+ *
2813
+ * @example
2814
+ * ```typescript
2815
+ * // Direct usage
2816
+ * const fruits = ['apple', 'banana', 'cherry'];
2817
+ * const entries = Arr.entries(fruits); // [[0, 'apple'], [1, 'banana'], [2, 'cherry']]
2818
+ *
2819
+ * // Curried usage
2820
+ * const getEntries = Arr.entries;
2821
+ * const result = getEntries(['a', 'b']); // [[0, 'a'], [1, 'b']]
2822
+ *
2823
+ * // With tuples
2824
+ * const tuple = [10, 20, 30] as const;
2825
+ * const tupleEntries = Arr.entries(tuple); // [[0, 10], [1, 20], [2, 30]]
2826
+ * ```
2827
+ */
2828
+ export function entries<E>(array: readonly E[]): ArrayIterator<readonly [SizeType.Arr, E]>;
2829
+ /**
2830
+ * Returns an iterable of values in the array.
2831
+ *
2832
+ * This function is essentially an identity function that returns a copy of the array.
2833
+ * It's included for API completeness and consistency with native Array methods.
2834
+ *
2835
+ * @template Ar The exact type of the input array.
2836
+ * @param array The array to get values from.
2837
+ * @returns A copy of the input array.
2838
+ *
2839
+ * @example
2840
+ * ```typescript
2841
+ * // Direct usage
2842
+ * const numbers = [1, 2, 3];
2843
+ * const values = Arr.values(numbers); // [1, 2, 3]
2844
+ *
2845
+ * // Curried usage
2846
+ * const getValues = Arr.values;
2847
+ * const result = getValues(['a', 'b']); // ['a', 'b']
2848
+ * ```
2849
+ */
2850
+ export function values<E>(array: readonly E[]): ArrayIterator<E>;
2851
+ /**
2852
+ * Returns an iterable of keys in the array.
2853
+ *
2854
+ * This function returns an array of branded indices (`SizeType.Arr`) for type safety.
2855
+ *
2856
+ * @template Ar The exact type of the input array.
2857
+ * @param array The array to get indices from.
2858
+ * @returns An array of indices.
2859
+ *
2860
+ * @example
2861
+ * ```typescript
2862
+ * // Direct usage
2863
+ * const fruits = ['apple', 'banana', 'cherry'];
2864
+ * const indices = Arr.indices(fruits); // [0, 1, 2]
2865
+ *
2866
+ * // Curried usage
2867
+ * const getIndices = Arr.indices;
2868
+ * const result = getIndices(['a', 'b']); // [0, 1]
2869
+ *
2870
+ * // Empty array
2871
+ * const empty: string[] = [];
2872
+ * const emptyIndices = Arr.indices(empty); // []
2873
+ * ```
2874
+ */
2875
+ export function indices<E>(array: readonly E[]): ArrayIterator<SizeType.Arr>;
2396
2876
  /**
2397
2877
  * Alias for `head`. Returns the first element of an array.
2398
2878
  * @see {@link head}
2399
2879
  */
2400
- export const first: typeof head;
2880
+ export const first: <Ar extends readonly unknown[]>(array: Ar) => Ar extends readonly [] ? Optional.None : Ar extends readonly [infer E, ...unknown[]] ? Optional.Some<E> : Ar extends NonEmptyArray<infer E> ? Optional.Some<E> : Optional<Ar[number]>;
2401
2881
  /**
2402
2882
  * Alias for `tail`. Returns all elements of an array except the first one.
2403
2883
  * @see {@link tail}
@@ -2423,6 +2903,21 @@ export declare namespace Arr {
2423
2903
  * @see {@link partition}
2424
2904
  */
2425
2905
  export const chunk: typeof partition;
2906
+ /**
2907
+ * Alias for `create`. Creates a new array of the specified length, with each position filled with the provided initial value.
2908
+ * @see {@link create}
2909
+ */
2910
+ export const newArray: <const V, N extends SizeType.ArgArr>(len: N, init: V) => N extends SmallUint ? ArrayOfLength<N, V> : N extends SizeType.ArgArrPositive ? NonEmptyArray<V> : readonly V[];
2911
+ /**
2912
+ * Alias for `size`. Returns the length of an array.
2913
+ * @see {@link size}
2914
+ */
2915
+ export const length: <Ar extends readonly unknown[]>(array: Ar) => Ar extends NonEmptyArray<unknown> ? IntersectBrand<PositiveNumber, SizeType.Arr> : SizeType.Arr;
2916
+ /**
2917
+ * Alias for `indices`. Returns an iterable of keys in the array.
2918
+ * @see {@link indices}
2919
+ */
2920
+ export const keys: typeof indices;
2426
2921
  export {};
2427
2922
  }
2428
2923
  //# sourceMappingURL=array-utils.d.mts.map