ts-data-forge 2.1.1 → 2.1.3

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 (103) hide show
  1. package/README.md +13 -15
  2. package/dist/array/array-utils.d.mts.map +1 -1
  3. package/dist/array/array-utils.mjs +9 -13
  4. package/dist/array/array-utils.mjs.map +1 -1
  5. package/dist/collections/imap.d.mts +1 -1
  6. package/dist/collections/imap.d.mts.map +1 -1
  7. package/dist/collections/imap.mjs +5 -5
  8. package/dist/collections/imap.mjs.map +1 -1
  9. package/dist/collections/iset-mapped.d.mts +1 -1
  10. package/dist/collections/iset-mapped.mjs +1 -1
  11. package/dist/collections/iset.d.mts +2 -2
  12. package/dist/collections/iset.mjs +4 -5
  13. package/dist/collections/iset.mjs.map +1 -1
  14. package/dist/collections/queue.d.mts +1 -1
  15. package/dist/collections/queue.d.mts.map +1 -1
  16. package/dist/collections/queue.mjs +7 -8
  17. package/dist/collections/queue.mjs.map +1 -1
  18. package/dist/collections/stack.d.mts +1 -1
  19. package/dist/collections/stack.d.mts.map +1 -1
  20. package/dist/collections/stack.mjs +6 -7
  21. package/dist/collections/stack.mjs.map +1 -1
  22. package/dist/entry-point.d.mts.map +1 -1
  23. package/dist/functional/match.d.mts.map +1 -1
  24. package/dist/functional/match.mjs +1 -6
  25. package/dist/functional/match.mjs.map +1 -1
  26. package/dist/functional/optional.d.mts.map +1 -1
  27. package/dist/functional/optional.mjs +6 -4
  28. package/dist/functional/optional.mjs.map +1 -1
  29. package/dist/functional/result.d.mts.map +1 -1
  30. package/dist/functional/result.mjs +1 -6
  31. package/dist/functional/result.mjs.map +1 -1
  32. package/dist/json/json.d.mts.map +1 -1
  33. package/dist/json/json.mjs +3 -3
  34. package/dist/json/json.mjs.map +1 -1
  35. package/dist/others/memoize-function.d.mts +1 -1
  36. package/dist/others/memoize-function.mjs +1 -1
  37. package/dist/others/unknown-to-string.d.mts +44 -77
  38. package/dist/others/unknown-to-string.d.mts.map +1 -1
  39. package/dist/others/unknown-to-string.mjs +51 -85
  40. package/dist/others/unknown-to-string.mjs.map +1 -1
  41. package/package.json +10 -1
  42. package/src/array/array-utils-creation.test.mts +9 -8
  43. package/src/array/array-utils-overload-type-error.test.mts +6 -2
  44. package/src/array/array-utils-search.test.mts +1 -1
  45. package/src/array/array-utils-slicing.test.mts +0 -42
  46. package/src/array/array-utils-transformation.test.mts +11 -186
  47. package/src/array/array-utils-validation.test.mts +27 -27
  48. package/src/array/array-utils.mts +8 -12
  49. package/src/collections/imap-mapped.test.mts +15 -11
  50. package/src/collections/imap.mts +6 -13
  51. package/src/collections/imap.test.mts +20 -19
  52. package/src/collections/iset-mapped.mts +1 -1
  53. package/src/collections/iset-mapped.test.mts +14 -104
  54. package/src/collections/iset.mts +5 -7
  55. package/src/collections/iset.test.mts +43 -34
  56. package/src/collections/queue.mts +12 -10
  57. package/src/collections/queue.test.mts +46 -44
  58. package/src/collections/stack.mts +10 -9
  59. package/src/collections/stack.test.mts +12 -10
  60. package/src/entry-point.mts +1 -0
  61. package/src/functional/match.mts +1 -5
  62. package/src/functional/optional.mts +6 -6
  63. package/src/functional/optional.test.mts +7 -7
  64. package/src/functional/result.mts +1 -5
  65. package/src/guard/is-non-empty-string.test.mts +1 -1
  66. package/src/guard/is-non-null-object.test.mts +3 -3
  67. package/src/guard/is-primitive.test.mts +6 -6
  68. package/src/guard/is-type.test.mts +8 -12
  69. package/src/iterator/range.test.mts +1 -1
  70. package/src/json/json.mts +4 -11
  71. package/src/json/json.test.mts +25 -28
  72. package/src/number/branded-types/finite-number.test.mts +2 -1
  73. package/src/number/branded-types/int.test.mts +2 -1
  74. package/src/number/branded-types/int16.test.mts +3 -2
  75. package/src/number/branded-types/int32.test.mts +3 -2
  76. package/src/number/branded-types/non-negative-finite-number.test.mts +3 -2
  77. package/src/number/branded-types/non-negative-int16.test.mts +3 -2
  78. package/src/number/branded-types/non-negative-int32.test.mts +3 -2
  79. package/src/number/branded-types/non-zero-finite-number.test.mts +4 -3
  80. package/src/number/branded-types/non-zero-int.test.mts +4 -3
  81. package/src/number/branded-types/non-zero-int16.test.mts +3 -2
  82. package/src/number/branded-types/non-zero-int32.test.mts +3 -2
  83. package/src/number/branded-types/non-zero-safe-int.test.mts +4 -3
  84. package/src/number/branded-types/non-zero-uint16.test.mts +3 -2
  85. package/src/number/branded-types/non-zero-uint32.test.mts +3 -2
  86. package/src/number/branded-types/positive-finite-number.test.mts +3 -2
  87. package/src/number/branded-types/positive-int.test.mts +3 -2
  88. package/src/number/branded-types/positive-int16.test.mts +3 -2
  89. package/src/number/branded-types/positive-int32.test.mts +3 -2
  90. package/src/number/branded-types/positive-safe-int.test.mts +3 -2
  91. package/src/number/branded-types/positive-uint16.test.mts +3 -2
  92. package/src/number/branded-types/positive-uint32.test.mts +3 -2
  93. package/src/number/branded-types/safe-int.test.mts +3 -2
  94. package/src/number/branded-types/safe-uint.test.mts +3 -2
  95. package/src/number/branded-types/uint.test.mts +3 -2
  96. package/src/number/branded-types/uint16.test.mts +3 -2
  97. package/src/number/branded-types/uint32.test.mts +3 -2
  98. package/src/object/object.test.mts +10 -10
  99. package/src/others/cast-readonly.test.mts +8 -8
  100. package/src/others/memoize-function.mts +1 -1
  101. package/src/others/memoize-function.test.mts +2 -2
  102. package/src/others/unknown-to-string.mts +52 -87
  103. package/src/others/unknown-to-string.test.mts +26 -58
@@ -1,6 +1,6 @@
1
1
  import { IMap } from '../collections/index.mjs';
2
2
  import { expectType } from '../expect-type.mjs';
3
- import { Optional } from '../functional/optional.mjs';
3
+ import { Optional } from '../functional/index.mjs';
4
4
  import { SafeUint } from '../number/index.mjs';
5
5
  import { Arr } from './array-utils.mjs';
6
6
 
@@ -132,47 +132,7 @@ describe('Arr transformations', () => {
132
132
  expect(result).toStrictEqual([[1, 2]]);
133
133
  });
134
134
 
135
- test('should work with empty array', () => {
136
- const empty: readonly number[] = [];
137
- const result = Arr.partition(empty, 2);
138
-
139
- expect(result).toStrictEqual([]);
140
- });
141
-
142
- test('should partition array into chunks', () => {
143
- const numbers = [1, 2, 3, 4, 5, 6];
144
- const result = Arr.partition(numbers, 2);
145
-
146
- expect(result).toStrictEqual([
147
- [1, 2],
148
- [3, 4],
149
- [5, 6],
150
- ]);
151
- });
152
-
153
- test('should handle arrays not evenly divisible by chunk size', () => {
154
- const numbers = [1, 2, 3, 4, 5];
155
- const result = Arr.partition(numbers, 2);
156
-
157
- expect(result).toStrictEqual([[1, 2], [3, 4], [5]]);
158
- });
159
-
160
- test('should work with chunk size < 2 (returns empty)', () => {
161
- const numbers = [1, 2, 3];
162
- const result = Arr.partition(numbers, 1);
163
-
164
- // According to docs, returns empty array if chunkSize < 2
165
- expect(result).toStrictEqual([]);
166
- });
167
-
168
- test('should work with chunk size larger than array', () => {
169
- const numbers = [1, 2];
170
- const result = Arr.partition(numbers, 5);
171
-
172
- expect(result).toStrictEqual([[1, 2]]);
173
- });
174
-
175
- test('should work with empty array', () => {
135
+ test('partition should work with empty array', () => {
176
136
  const empty: readonly number[] = [];
177
137
  const result = Arr.partition(empty, 2);
178
138
 
@@ -180,19 +140,6 @@ describe('Arr transformations', () => {
180
140
  });
181
141
  });
182
142
 
183
- describe('toReversed', () => {
184
- {
185
- const xs = [1, 2, 3] as const;
186
- const result = xs.toReversed();
187
-
188
- expectType<typeof result, (1 | 2 | 3)[]>('=');
189
-
190
- test('case 1', () => {
191
- expect(result).toStrictEqual([3, 2, 1]);
192
- });
193
- }
194
- });
195
-
196
143
  describe('toSorted', () => {
197
144
  {
198
145
  const xs = [2, 1, 3] as const;
@@ -294,37 +241,7 @@ describe('Arr transformations', () => {
294
241
  expect(result).toStrictEqual([]);
295
242
  });
296
243
 
297
- test('should sort by key function', () => {
298
- const people = [
299
- { name: 'Alice', age: 30 },
300
- { name: 'Bob', age: 20 },
301
- { name: 'Charlie', age: 25 },
302
- ];
303
- const result = Arr.toSortedBy(people, (person) => person.age);
304
-
305
- expect(result).toHaveLength(3);
306
- expect(result[0]?.name).toBe('Bob');
307
- expect(result[1]?.name).toBe('Charlie');
308
- expect(result[2]?.name).toBe('Alice');
309
- });
310
-
311
- test('should work with string sorting', () => {
312
- const words = ['banana', 'apple', 'cherry'];
313
- const result = Arr.toSortedBy(
314
- words,
315
- (word: string) => word,
316
- (a: string, b: string) => a.localeCompare(b),
317
- );
318
- expect(result).toStrictEqual(['apple', 'banana', 'cherry']);
319
- });
320
-
321
- test('should work with custom key extraction', () => {
322
- const items = ['hello', 'hi', 'welcome', 'bye'];
323
- const result = Arr.toSortedBy(items, (item) => item.length);
324
- expect(result).toStrictEqual(['hi', 'bye', 'hello', 'welcome']);
325
- });
326
-
327
- test('should work with empty array', () => {
244
+ test('toSortedBy should work with empty array', () => {
328
245
  const empty: readonly { value: number }[] = [];
329
246
  const result = Arr.toSortedBy(empty, (item) => item.value);
330
247
  expect(result).toStrictEqual([]);
@@ -452,68 +369,6 @@ describe('Arr transformations', () => {
452
369
  expect(all.value).toStrictEqual([1, 2, 3, 4]);
453
370
  }
454
371
  });
455
-
456
- test('should group elements by key', () => {
457
- const array = [
458
- { type: 'fruit', name: 'apple' },
459
- { type: 'vegetable', name: 'carrot' },
460
- { type: 'fruit', name: 'banana' },
461
- ];
462
- const grouped = Arr.groupBy(array, (item) => item.type);
463
-
464
- expect(grouped.size).toBe(2);
465
- const fruits = grouped.get('fruit');
466
- const vegetables = grouped.get('vegetable');
467
-
468
- expect(Optional.isSome(fruits)).toBe(true);
469
- expect(Optional.isSome(vegetables)).toBe(true);
470
-
471
- if (Optional.isSome(fruits)) {
472
- expect(fruits.value).toHaveLength(2);
473
- expect(fruits.value[0]?.name).toBe('apple');
474
- expect(fruits.value[1]?.name).toBe('banana');
475
- }
476
-
477
- if (Optional.isSome(vegetables)) {
478
- expect(vegetables.value).toHaveLength(1);
479
- expect(vegetables.value[0]?.name).toBe('carrot');
480
- }
481
- });
482
-
483
- test('should work with numeric keys', () => {
484
- const numbers = [1, 2, 3, 4, 5, 6];
485
- const grouped = Arr.groupBy(numbers, (n) => n % 2);
486
-
487
- expect(grouped.size).toBe(2);
488
- const evens = grouped.get(0);
489
- const odds = grouped.get(1);
490
-
491
- if (Optional.isSome(evens)) {
492
- expect(evens.value).toStrictEqual([2, 4, 6]);
493
- }
494
-
495
- if (Optional.isSome(odds)) {
496
- expect(odds.value).toStrictEqual([1, 3, 5]);
497
- }
498
- });
499
-
500
- test('should work with empty array', () => {
501
- const empty: readonly number[] = [];
502
- const grouped = Arr.groupBy(empty, (n) => n % 2);
503
- expect(grouped.size).toBe(0);
504
- });
505
-
506
- test('should handle all elements in same group', () => {
507
- const array = [1, 2, 3, 4];
508
- const grouped = Arr.groupBy(array, () => 'all');
509
-
510
- expect(grouped.size).toBe(1);
511
- const all = grouped.get('all');
512
-
513
- if (Optional.isSome(all)) {
514
- expect(all.value).toStrictEqual([1, 2, 3, 4]);
515
- }
516
- });
517
372
  });
518
373
 
519
374
  describe('zip', () => {
@@ -632,41 +487,6 @@ describe('Arr transformations', () => {
632
487
  const result = Arr.zip(arr1, arr2);
633
488
  expect(result).toStrictEqual([]);
634
489
  });
635
-
636
- test('should zip two arrays', () => {
637
- const arr1 = [1, 2, 3];
638
- const arr2 = ['a', 'b', 'c'];
639
- const result = Arr.zip(arr1, arr2);
640
- expect(result).toStrictEqual([
641
- [1, 'a'],
642
- [2, 'b'],
643
- [3, 'c'],
644
- ]);
645
- });
646
-
647
- test('should handle arrays of different lengths', () => {
648
- const arr1 = [1, 2, 3, 4];
649
- const arr2 = ['a', 'b'];
650
- const result = Arr.zip(arr1, arr2);
651
- expect(result).toStrictEqual([
652
- [1, 'a'],
653
- [2, 'b'],
654
- ]);
655
- });
656
-
657
- test('should work with empty arrays', () => {
658
- const arr1: readonly number[] = [];
659
- const arr2: readonly string[] = [];
660
- const result = Arr.zip(arr1, arr2);
661
- expect(result).toStrictEqual([]);
662
- });
663
-
664
- test('should handle one empty array', () => {
665
- const arr1 = [1, 2, 3];
666
- const arr2: readonly string[] = [];
667
- const result = Arr.zip(arr1, arr2);
668
- expect(result).toStrictEqual([]);
669
- });
670
490
  });
671
491
 
672
492
  describe('filterNot', () => {
@@ -816,6 +636,11 @@ describe('Arr transformations', () => {
816
636
 
817
637
  describe('toReversed', () => {
818
638
  {
639
+ const xs = [1, 2, 3] as const;
640
+ const _nativeResult = xs.toReversed();
641
+
642
+ expectType<typeof _nativeResult, (1 | 2 | 3)[]>('=');
643
+
819
644
  const result = Arr.toReversed([1, 2, 3]);
820
645
 
821
646
  expectType<typeof result, readonly [3, 2, 1]>('=');
@@ -1197,15 +1022,15 @@ describe('Arr transformations', () => {
1197
1022
  test('should search from end to beginning', () => {
1198
1023
  // Verify search order by using side effects
1199
1024
  const numbers = [1, 2, 3, 4, 5];
1200
- const searchOrder: number[] = [];
1025
+ const mut_searchOrder: number[] = [];
1201
1026
 
1202
1027
  Arr.findLastIndex(numbers, (val, idx) => {
1203
- searchOrder.push(idx);
1028
+ mut_searchOrder.push(idx);
1204
1029
  return val === 3;
1205
1030
  });
1206
1031
 
1207
1032
  // Should search from end: 4, 3, 2 (stops at 2 when found)
1208
- expect(searchOrder).toStrictEqual([4, 3, 2]);
1033
+ expect(mut_searchOrder).toStrictEqual([4, 3, 2]);
1209
1034
  });
1210
1035
 
1211
1036
  test('should handle single element array', () => {
@@ -19,14 +19,16 @@ describe('Arr validations', () => {
19
19
  });
20
20
 
21
21
  test('should refine union types correctly', () => {
22
- function processValue(value: string | readonly number[] | null): number {
22
+ const processValue = (
23
+ value: string | readonly number[] | null,
24
+ ): number => {
23
25
  if (Arr.isArray(value)) {
24
26
  // value should be typed as number[]
25
27
  expectType<typeof value, readonly number[]>('=');
26
28
  return value.length;
27
29
  }
28
30
  return 0;
29
- }
31
+ };
30
32
 
31
33
  expect(processValue([1, 2, 3])).toBe(3);
32
34
  expect(processValue('hello')).toBe(0);
@@ -37,7 +39,7 @@ describe('Arr validations', () => {
37
39
  const readonlyArray: readonly number[] = [1, 2, 3];
38
40
  if (Arr.isArray(readonlyArray)) {
39
41
  expectType<typeof readonlyArray, readonly number[]>('=');
40
- expect(readonlyArray.length).toBe(3);
42
+ expect(readonlyArray).toHaveLength(3);
41
43
  }
42
44
  });
43
45
 
@@ -45,25 +47,25 @@ describe('Arr validations', () => {
45
47
  const mutableArray: number[] = [1, 2, 3];
46
48
  if (Arr.isArray(mutableArray)) {
47
49
  expectType<typeof mutableArray, number[]>('=');
48
- expect(mutableArray.length).toBe(3);
50
+ expect(mutableArray).toHaveLength(3);
49
51
  }
50
52
  });
51
53
 
52
54
  test('should exclude impossible array types from unions', () => {
53
- function checkUnion(
54
- value: string | boolean | readonly number[] | { readonly a: number },
55
- ): number {
55
+ const checkUnion = (
56
+ value: string | boolean | readonly number[] | Readonly<{ a: number }>,
57
+ ): number => {
56
58
  if (Arr.isArray(value)) {
57
59
  // Only number[] should remain
58
60
  expectType<typeof value, readonly number[]>('=');
59
61
  return value.length;
60
62
  }
61
63
  // Non-array types
62
- expectType<typeof value, string | boolean | { readonly a: number }>(
64
+ expectType<typeof value, string | boolean | Readonly<{ a: number }>>(
63
65
  '=',
64
66
  );
65
67
  return -1;
66
- }
68
+ };
67
69
 
68
70
  expect(checkUnion([1, 2])).toBe(2);
69
71
  expect(checkUnion('test')).toBe(-1);
@@ -72,17 +74,17 @@ describe('Arr validations', () => {
72
74
  });
73
75
 
74
76
  test('should exclude impossible array types from unions (including unknown)', () => {
75
- function checkUnion(
77
+ const checkUnion = (
76
78
  value:
77
79
  | string
78
80
  | boolean
79
81
  | readonly number[]
80
- | { readonly a: number }
82
+ | Readonly<{ a: number }>
81
83
  // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
82
84
  | unknown
83
85
  // eslint-disable-next-line @typescript-eslint/no-restricted-types
84
86
  | object,
85
- ): number {
87
+ ): number => {
86
88
  if (Arr.isArray(value)) {
87
89
  // Only number[] should remain
88
90
  expectType<typeof value, readonly unknown[]>('=');
@@ -93,14 +95,14 @@ describe('Arr validations', () => {
93
95
  typeof value,
94
96
  | string
95
97
  | boolean
96
- | { readonly a: number }
98
+ | Readonly<{ a: number }>
97
99
  // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
98
100
  | unknown
99
101
  // eslint-disable-next-line @typescript-eslint/no-restricted-types
100
102
  | object
101
103
  >('=');
102
104
  return -1;
103
- }
105
+ };
104
106
 
105
107
  expect(checkUnion([1, 2])).toBe(2);
106
108
  expect(checkUnion('test')).toBe(-1);
@@ -126,7 +128,7 @@ describe('Arr validations', () => {
126
128
  const value: unknown = [1, 2, 3];
127
129
  if (Arr.isArray(value)) {
128
130
  expectType<typeof value, readonly unknown[]>('=');
129
- expect(value.length).toBe(3);
131
+ expect(value).toHaveLength(3);
130
132
  }
131
133
  });
132
134
 
@@ -186,13 +188,13 @@ describe('Arr validations', () => {
186
188
  });
187
189
 
188
190
  test('should work with generic function', () => {
189
- function processGeneric<T>(value: T | readonly number[]): number {
191
+ const processGeneric = <T,>(value: T | readonly number[]): number => {
190
192
  if (Arr.isArray(value)) {
191
193
  // Type is narrowed to array type within this block
192
194
  return value.length;
193
195
  }
194
196
  return 0;
195
- }
197
+ };
196
198
  expect(processGeneric([1, 2, 3])).toBe(3);
197
199
  expect(processGeneric('hello')).toBe(0);
198
200
  });
@@ -207,14 +209,14 @@ describe('Arr validations', () => {
207
209
 
208
210
  test('should work with conditional types', () => {
209
211
  type ArrayOrValue<T> = T extends readonly unknown[] ? T : readonly T[];
210
- function makeArray<T>(value: T): ArrayOrValue<T> {
212
+ const makeArray = <T,>(value: T): ArrayOrValue<T> => {
211
213
  if (Arr.isArray(value)) {
212
214
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
213
215
  return value as ArrayOrValue<T>;
214
216
  }
215
217
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
216
218
  return [value] as ArrayOrValue<T>;
217
- }
219
+ };
218
220
  expect(makeArray([1, 2, 3])).toStrictEqual([1, 2, 3]);
219
221
  expect(makeArray(5)).toStrictEqual([5]);
220
222
  });
@@ -229,9 +231,7 @@ describe('Arr validations', () => {
229
231
  });
230
232
 
231
233
  test('should work with branded types', () => {
232
- type BrandedArray = readonly number[] & {
233
- readonly __brand: unique symbol;
234
- };
234
+ type BrandedArray = readonly number[] & Readonly<{ __brand: unknown }>;
235
235
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
236
236
  const branded = [1, 2, 3] as unknown as BrandedArray;
237
237
  if (Arr.isArray(branded)) {
@@ -248,7 +248,7 @@ describe('Arr validations', () => {
248
248
  | null;
249
249
 
250
250
  // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
251
- function processComplex(value: ComplexUnion): number {
251
+ const processComplex = (value: ComplexUnion): number => {
252
252
  if (Arr.isArray(value)) {
253
253
  expectType<typeof value, readonly number[]>('=');
254
254
  return value.length;
@@ -267,7 +267,7 @@ describe('Arr validations', () => {
267
267
  | { type: 'object'; data: Record<string, unknown> }
268
268
  >('=');
269
269
  return -1;
270
- }
270
+ };
271
271
 
272
272
  expect(processComplex([1, 2, 3])).toBe(3);
273
273
  expect(processComplex('test')).toBe(4);
@@ -293,7 +293,7 @@ describe('Arr validations', () => {
293
293
  const sym = Symbol('test');
294
294
  const arrWithSymbol = Object.assign([1, 2, 3], { [sym]: 'value' });
295
295
  if (Arr.isArray(arrWithSymbol)) {
296
- expect(arrWithSymbol.length).toBe(3);
296
+ expect(arrWithSymbol).toHaveLength(3);
297
297
  }
298
298
  });
299
299
  });
@@ -390,7 +390,7 @@ describe('Arr validations', () => {
390
390
  const array: readonly number[] = [1, 2, 3];
391
391
  if (Arr.isArrayOfLength(array, 3)) {
392
392
  expectType<typeof array, ArrayOfLength<3, number>>('=');
393
- expect(array.length).toBe(3);
393
+ expect(array).toHaveLength(3);
394
394
  }
395
395
  });
396
396
  });
@@ -455,7 +455,7 @@ describe('Arr validations', () => {
455
455
  const array: readonly number[] = [1, 2, 3];
456
456
  if (Arr.isArrayAtLeastLength(array, 2)) {
457
457
  expectType<typeof array, ArrayAtLeastLen<2, number>>('=');
458
- expect(array.length >= 2).toBe(true);
458
+ expect(array.length).toBeGreaterThanOrEqual(2);
459
459
  }
460
460
  });
461
461
  });
@@ -2133,9 +2133,9 @@ export namespace Arr {
2133
2133
  switch (args.length) {
2134
2134
  case 3: {
2135
2135
  const [array, value, [start, end]] = args;
2136
- const cp: (E | V)[] = castMutable(copy(array));
2137
- cp.fill(value, start, end);
2138
- return cp;
2136
+ const mut_cp: (E | V)[] = castMutable(copy(array));
2137
+ mut_cp.fill(value, start, end);
2138
+ return mut_cp;
2139
2139
  }
2140
2140
  case 2: {
2141
2141
  const [value, fillRange] = args;
@@ -2669,7 +2669,7 @@ export namespace Arr {
2669
2669
  const [array, searchElement] = args;
2670
2670
 
2671
2671
  const index = array.indexOf(searchElement);
2672
- return index >= 0 ? asUint32(index) : -1;
2672
+ return index !== -1 ? asUint32(index) : -1;
2673
2673
  }
2674
2674
  case 1: {
2675
2675
  const [searchElement] = args;
@@ -2702,7 +2702,7 @@ export namespace Arr {
2702
2702
  case 3: {
2703
2703
  const [array, searchElement, fromIndex] = args;
2704
2704
  const index = array.indexOf(searchElement, fromIndex);
2705
- return index >= 0 ? asUint32(index) : -1;
2705
+ return index !== -1 ? asUint32(index) : -1;
2706
2706
  }
2707
2707
  case 2: {
2708
2708
  const [searchElement, fromIndex] = args;
@@ -2750,7 +2750,7 @@ export namespace Arr {
2750
2750
  case 2: {
2751
2751
  const [array, searchElement] = args;
2752
2752
  const index = array.lastIndexOf(searchElement);
2753
- return index >= 0 ? asUint32(index) : -1;
2753
+ return index !== -1 ? asUint32(index) : -1;
2754
2754
  }
2755
2755
  case 1: {
2756
2756
  const [searchElement] = args;
@@ -2785,7 +2785,7 @@ export namespace Arr {
2785
2785
 
2786
2786
  const index = array.lastIndexOf(searchElement, fromIndex);
2787
2787
 
2788
- return index >= 0 ? asUint32(index) : -1;
2788
+ return index !== -1 ? asUint32(index) : -1;
2789
2789
  }
2790
2790
  case 2: {
2791
2791
  const [searchElement, fromIndex] = args;
@@ -3460,11 +3460,7 @@ export namespace Arr {
3460
3460
  return Result.ok(result);
3461
3461
  } catch (error) {
3462
3462
  return Result.err(
3463
- error instanceof Error
3464
- ? error
3465
- : pipe(unknownToString(error))
3466
- .map(Result.unwrapOkOr('Failed to join array'))
3467
- .map((e) => new Error(e)).value,
3463
+ error instanceof Error ? error : new Error(unknownToString(error)),
3468
3464
  );
3469
3465
  }
3470
3466
  };
@@ -83,10 +83,12 @@ describe('IMapMapped.create', () => {
83
83
 
84
84
  test('should handle complex key transformations', () => {
85
85
  type ComplexKey = { nested: { id: number }; arr: number[] };
86
- const complexKeyToString = (key: {
87
- readonly nested: { readonly id: number };
88
- readonly arr: readonly number[];
89
- }): string => `${key.nested.id}_${key.arr.join(',')}`;
86
+ const complexKeyToString = (
87
+ key: DeepReadonly<{
88
+ nested: { id: number };
89
+ arr: number[];
90
+ }>,
91
+ ): string => `${key.nested.id}_${key.arr.join(',')}`;
90
92
  const stringToComplexKey = (str: string): ComplexKey => {
91
93
  const [idStr, arrStr] = str.split('_');
92
94
  return {
@@ -527,6 +529,7 @@ describe('IMapMapped.some', () => {
527
529
  testKeyToString,
528
530
  stringToTestKey,
529
531
  );
532
+ // eslint-disable-next-line unicorn/prefer-includes
530
533
  expect(map.some((value) => value === 'Alice')).toBe(true);
531
534
  });
532
535
 
@@ -539,6 +542,7 @@ describe('IMapMapped.some', () => {
539
542
  testKeyToString,
540
543
  stringToTestKey,
541
544
  );
545
+ // eslint-disable-next-line unicorn/prefer-includes
542
546
  expect(map.some((value) => value === 'Charlie')).toBe(false);
543
547
  });
544
548
 
@@ -704,15 +708,15 @@ describe('IMapMapped.forEach', () => {
704
708
  testKeyToString,
705
709
  stringToTestKey,
706
710
  );
707
- const collected: [TestKey, string][] = [];
711
+ const mut_collected: [TestKey, string][] = [];
708
712
 
709
- map.forEach((value, key) => {
710
- collected.push([key, value]);
711
- });
713
+ for (const [key, value] of map.entries()) {
714
+ mut_collected.push([key, value]);
715
+ }
712
716
 
713
- expect(collected).toHaveLength(2);
714
- expect(collected).toContainEqual([{ id: 1, type: 'user' }, 'Alice']);
715
- expect(collected).toContainEqual([{ id: 2, type: 'admin' }, 'Bob']);
717
+ expect(mut_collected).toHaveLength(2);
718
+ expect(mut_collected).toContainEqual([{ id: 1, type: 'user' }, 'Alice']);
719
+ expect(mut_collected).toContainEqual([{ id: 2, type: 'admin' }, 'Bob']);
716
720
  });
717
721
  });
718
722
 
@@ -1,7 +1,6 @@
1
- import { Optional, Result } from '../functional/index.mjs';
1
+ import { Optional } from '../functional/index.mjs';
2
2
  import { asUint32 } from '../number/index.mjs';
3
- import { tp } from '../others/index.mjs';
4
- import { unknownToString } from '../others/unknown-to-string.mjs';
3
+ import { tp, unknownToString } from '../others/index.mjs';
5
4
 
6
5
  /**
7
6
  * Interface for an immutable map with O(1) lookup performance and functional programming patterns.
@@ -323,7 +322,7 @@ export namespace IMap {
323
322
  *
324
323
  * // From custom iterable
325
324
  * function* generateEntries(): Generator<[string, number]> {
326
- * for (let i = 0; i < 3; i++) {
325
+ * for (const i of range(3)) {
327
326
  * yield [`item${i}`, i * 10];
328
327
  * }
329
328
  * }
@@ -488,9 +487,7 @@ class IMapClass<K extends MapSetKeyType, V>
488
487
  if (!this.has(key)) {
489
488
  if (this.#showNotFoundMessage) {
490
489
  const keyStr = unknownToString(key);
491
- console.warn(
492
- `IMap.delete: key not found: ${Result.isOk(keyStr) ? keyStr.value : '<error converting key to string>'}`,
493
- );
490
+ console.warn(`IMap.delete: key not found: ${keyStr}`);
494
491
  }
495
492
  return this;
496
493
  }
@@ -519,9 +516,7 @@ class IMapClass<K extends MapSetKeyType, V>
519
516
  if (Optional.isNone(curr)) {
520
517
  if (this.#showNotFoundMessage) {
521
518
  const keyStr = unknownToString(key);
522
- console.warn(
523
- `IMap.update: key not found: ${Result.isOk(keyStr) ? keyStr.value : '<error converting key to string>'}`,
524
- );
519
+ console.warn(`IMap.update: key not found: ${keyStr}`);
525
520
  }
526
521
  return this;
527
522
  }
@@ -561,9 +556,7 @@ class IMapClass<K extends MapSetKeyType, V>
561
556
  if (!mut_result.has(key) || curr === undefined) {
562
557
  if (this.#showNotFoundMessage) {
563
558
  const keyStr = unknownToString(key);
564
- console.warn(
565
- `IMap.withMutations: key not found: ${Result.isOk(keyStr) ? keyStr.value : '<error converting key to string>'}`,
566
- );
559
+ console.warn(`IMap.withMutations: key not found: ${keyStr}`);
567
560
  }
568
561
  break;
569
562
  }