ts-data-forge 6.4.0 → 6.6.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 (181) hide show
  1. package/README.md +5 -3
  2. package/dist/array/impl/array-utils-element-access.d.mts +5 -5
  3. package/dist/array/impl/array-utils-element-access.mjs +4 -4
  4. package/dist/array/impl/array-utils-iterators.d.mts +1 -1
  5. package/dist/array/impl/array-utils-iterators.mjs +1 -1
  6. package/dist/array/impl/array-utils-modification.d.mts +4 -4
  7. package/dist/array/impl/array-utils-reducing-value.d.mts +5 -5
  8. package/dist/array/impl/array-utils-reducing-value.d.mts.map +1 -1
  9. package/dist/array/impl/array-utils-reducing-value.mjs +1 -0
  10. package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
  11. package/dist/array/impl/array-utils-search.d.mts +8 -8
  12. package/dist/array/impl/array-utils-set-op.d.mts.map +1 -1
  13. package/dist/array/impl/array-utils-set-op.mjs +3 -1
  14. package/dist/array/impl/array-utils-set-op.mjs.map +1 -1
  15. package/dist/array/impl/array-utils-size.d.mts +1 -1
  16. package/dist/array/impl/array-utils-size.mjs +1 -1
  17. package/dist/array/impl/array-utils-slice-clamped.d.mts +1 -1
  18. package/dist/array/impl/array-utils-slicing.d.mts +3 -3
  19. package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
  20. package/dist/array/impl/array-utils-validation.d.mts +7 -7
  21. package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
  22. package/dist/array/impl/array-utils-validation.mjs +22 -12
  23. package/dist/array/impl/array-utils-validation.mjs.map +1 -1
  24. package/dist/collections/imap-mapped.d.mts +5 -12
  25. package/dist/collections/imap-mapped.d.mts.map +1 -1
  26. package/dist/collections/imap-mapped.mjs.map +1 -1
  27. package/dist/collections/imap.d.mts +24 -28
  28. package/dist/collections/imap.d.mts.map +1 -1
  29. package/dist/collections/imap.mjs +1 -1
  30. package/dist/collections/imap.mjs.map +1 -1
  31. package/dist/collections/iset-mapped.d.mts +8 -14
  32. package/dist/collections/iset-mapped.d.mts.map +1 -1
  33. package/dist/collections/iset-mapped.mjs.map +1 -1
  34. package/dist/collections/iset.d.mts +9 -23
  35. package/dist/collections/iset.d.mts.map +1 -1
  36. package/dist/collections/iset.mjs +1 -0
  37. package/dist/collections/iset.mjs.map +1 -1
  38. package/dist/entry-point.mjs +1 -0
  39. package/dist/entry-point.mjs.map +1 -1
  40. package/dist/functional/optional/impl/optional-is-optional.d.mts +1 -1
  41. package/dist/functional/optional/impl/optional-is-optional.d.mts.map +1 -1
  42. package/dist/functional/optional/impl/optional-is-optional.mjs +6 -5
  43. package/dist/functional/optional/impl/optional-is-optional.mjs.map +1 -1
  44. package/dist/functional/optional/impl/optional-some.d.mts.map +1 -1
  45. package/dist/functional/optional/impl/optional-some.mjs.map +1 -1
  46. package/dist/functional/optional/impl/optional-zip.d.mts +1 -1
  47. package/dist/functional/optional/impl/optional-zip.mjs +1 -1
  48. package/dist/functional/result/impl/result-err.d.mts.map +1 -1
  49. package/dist/functional/result/impl/result-err.mjs.map +1 -1
  50. package/dist/functional/result/impl/result-is-result.d.mts +1 -1
  51. package/dist/functional/result/impl/result-is-result.mjs +1 -1
  52. package/dist/functional/result/impl/result-ok.d.mts.map +1 -1
  53. package/dist/functional/result/impl/result-ok.mjs.map +1 -1
  54. package/dist/functional/result/impl/result-unwrap-err-throw.mjs +1 -0
  55. package/dist/functional/result/impl/result-unwrap-err-throw.mjs.map +1 -1
  56. package/dist/functional/result/impl/result-unwrap-throw.mjs +1 -0
  57. package/dist/functional/result/impl/result-unwrap-throw.mjs.map +1 -1
  58. package/dist/functional/ternary-result/impl/ternary-result-err.d.mts.map +1 -1
  59. package/dist/functional/ternary-result/impl/ternary-result-err.mjs.map +1 -1
  60. package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.d.mts +1 -1
  61. package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.mjs +1 -1
  62. package/dist/functional/ternary-result/impl/ternary-result-ok.d.mts.map +1 -1
  63. package/dist/functional/ternary-result/impl/ternary-result-ok.mjs.map +1 -1
  64. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs +1 -0
  65. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs.map +1 -1
  66. package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs +1 -0
  67. package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs.map +1 -1
  68. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs +1 -0
  69. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs.map +1 -1
  70. package/dist/functional/ternary-result/impl/ternary-result-warn.d.mts.map +1 -1
  71. package/dist/functional/ternary-result/impl/ternary-result-warn.mjs.map +1 -1
  72. package/dist/guard/has-key.d.mts +3 -1
  73. package/dist/guard/has-key.d.mts.map +1 -1
  74. package/dist/guard/has-key.mjs +6 -2
  75. package/dist/guard/has-key.mjs.map +1 -1
  76. package/dist/guard/is-non-null-object.d.mts.map +1 -1
  77. package/dist/guard/is-non-null-object.mjs +3 -1
  78. package/dist/guard/is-non-null-object.mjs.map +1 -1
  79. package/dist/guard/is-record.d.mts +2 -2
  80. package/dist/guard/is-record.mjs +2 -2
  81. package/dist/guard/is-type.d.mts +15 -15
  82. package/dist/guard/is-type.mjs +15 -15
  83. package/dist/guard/key-is-in.d.mts.map +1 -1
  84. package/dist/guard/key-is-in.mjs +3 -1
  85. package/dist/guard/key-is-in.mjs.map +1 -1
  86. package/dist/index.mjs +1 -0
  87. package/dist/index.mjs.map +1 -1
  88. package/dist/json/json.d.mts +3 -3
  89. package/dist/json/json.mjs +4 -3
  90. package/dist/json/json.mjs.map +1 -1
  91. package/dist/number/branded-types/non-zero-safe-int.mjs +2 -2
  92. package/dist/number/branded-types/positive-safe-int.mjs +1 -1
  93. package/dist/number/branded-types/safe-int.mjs +2 -2
  94. package/dist/number/branded-types/safe-uint.mjs +1 -1
  95. package/dist/number/num.mjs +1 -1
  96. package/dist/object/object.d.mts +36 -8
  97. package/dist/object/object.d.mts.map +1 -1
  98. package/dist/object/object.mjs +28 -6
  99. package/dist/object/object.mjs.map +1 -1
  100. package/dist/others/fast-deep-equal.d.mts +8 -0
  101. package/dist/others/fast-deep-equal.d.mts.map +1 -0
  102. package/dist/others/fast-deep-equal.mjs +72 -0
  103. package/dist/others/fast-deep-equal.mjs.map +1 -0
  104. package/dist/others/index.d.mts +1 -0
  105. package/dist/others/index.d.mts.map +1 -1
  106. package/dist/others/index.mjs +1 -0
  107. package/dist/others/index.mjs.map +1 -1
  108. package/package.json +34 -29
  109. package/src/array/impl/array-utils-creation.test.mts +13 -10
  110. package/src/array/impl/array-utils-element-access.mts +5 -5
  111. package/src/array/impl/array-utils-element-access.test.mts +5 -5
  112. package/src/array/impl/array-utils-iterators.mts +1 -1
  113. package/src/array/impl/array-utils-iterators.test.mts +6 -6
  114. package/src/array/impl/array-utils-modification.mts +4 -4
  115. package/src/array/impl/array-utils-modification.test.mts +12 -12
  116. package/src/array/impl/array-utils-overload-type-error.test.mts +1 -1
  117. package/src/array/impl/array-utils-reducing-value.mts +6 -5
  118. package/src/array/impl/array-utils-reducing-value.test.mts +9 -9
  119. package/src/array/impl/array-utils-search.mts +8 -8
  120. package/src/array/impl/array-utils-search.test.mts +35 -35
  121. package/src/array/impl/array-utils-set-op.mts +1 -0
  122. package/src/array/impl/array-utils-set-op.test.mts +2 -2
  123. package/src/array/impl/array-utils-size.mts +1 -1
  124. package/src/array/impl/array-utils-size.test.mts +1 -1
  125. package/src/array/impl/array-utils-slice-clamped.mts +1 -1
  126. package/src/array/impl/array-utils-slice-clamped.test.mts +5 -5
  127. package/src/array/impl/array-utils-slicing.mts +3 -3
  128. package/src/array/impl/array-utils-slicing.test.mts +5 -5
  129. package/src/array/impl/array-utils-transformation.mts +1 -1
  130. package/src/array/impl/array-utils-transformation.test.mts +53 -53
  131. package/src/array/impl/array-utils-validation.mts +18 -10
  132. package/src/array/impl/array-utils-validation.test.mts +34 -29
  133. package/src/array/impl/array.test.mts +1 -1
  134. package/src/collections/imap-mapped.mts +4 -10
  135. package/src/collections/imap-mapped.test.mts +9 -9
  136. package/src/collections/imap.mts +24 -27
  137. package/src/collections/imap.test.mts +6 -6
  138. package/src/collections/iset-mapped.mts +12 -16
  139. package/src/collections/iset-mapped.test.mts +6 -6
  140. package/src/collections/iset.mts +14 -25
  141. package/src/collections/queue.test.mts +2 -1
  142. package/src/collections/stack.test.mts +3 -3
  143. package/src/functional/optional/impl/optional-is-optional.mts +6 -6
  144. package/src/functional/optional/impl/optional-some.mts +5 -4
  145. package/src/functional/optional/impl/optional-zip.mts +1 -1
  146. package/src/functional/result/impl/result-err.mts +5 -4
  147. package/src/functional/result/impl/result-is-result.mts +1 -1
  148. package/src/functional/result/impl/result-ok.mts +5 -4
  149. package/src/functional/result.test.mts +2 -2
  150. package/src/functional/ternary-result/impl/ternary-result-err.mts +5 -4
  151. package/src/functional/ternary-result/impl/ternary-result-is-ternary-result.mts +1 -1
  152. package/src/functional/ternary-result/impl/ternary-result-ok.mts +5 -4
  153. package/src/functional/ternary-result/impl/ternary-result-warn.mts +6 -5
  154. package/src/guard/has-key.mts +6 -2
  155. package/src/guard/is-error.test.mts +1 -1
  156. package/src/guard/is-non-empty-string.test.mts +1 -1
  157. package/src/guard/is-non-null-object.mts +1 -0
  158. package/src/guard/is-non-null-object.test.mts +4 -3
  159. package/src/guard/is-primitive.test.mts +1 -1
  160. package/src/guard/is-record.mts +2 -2
  161. package/src/guard/is-record.test.mts +2 -2
  162. package/src/guard/is-type.mts +15 -15
  163. package/src/guard/is-type.test.mts +2 -2
  164. package/src/guard/key-is-in.mts +3 -1
  165. package/src/json/json.mts +4 -3
  166. package/src/json/json.test.mts +20 -19
  167. package/src/number/branded-types/non-zero-safe-int.mts +2 -2
  168. package/src/number/branded-types/positive-safe-int.mts +1 -1
  169. package/src/number/branded-types/safe-int.mts +2 -2
  170. package/src/number/branded-types/safe-uint.mts +1 -1
  171. package/src/number/num.mts +1 -1
  172. package/src/object/object.mts +54 -8
  173. package/src/object/object.test.mts +70 -7
  174. package/src/others/cast-mutable.test.mts +3 -3
  175. package/src/others/cast-readonly.test.mts +10 -5
  176. package/src/others/fast-deep-equal.mts +98 -0
  177. package/src/others/fast-deep-equal.test.mts +771 -0
  178. package/src/others/index.mts +1 -0
  179. package/src/others/map-nullable.test.mts +8 -8
  180. package/src/others/memoize-function.test.mts +20 -8
  181. package/src/others/unknown-to-string.test.mts +8 -8
@@ -56,7 +56,7 @@ describe('Arr validations', () => {
56
56
  });
57
57
 
58
58
  test('should work with readonly arrays', () => {
59
- const readonlyArray: readonly number[] = [1, 2, 3];
59
+ const readonlyArray: readonly number[] = [1, 2, 3] as const;
60
60
 
61
61
  if (isArray(readonlyArray)) {
62
62
  expectType<typeof readonlyArray, readonly number[]>('=');
@@ -66,10 +66,11 @@ describe('Arr validations', () => {
66
66
  });
67
67
 
68
68
  test('should work with mutable arrays', () => {
69
- const mutableArray: readonly number[] = [1, 2, 3];
69
+ // transformer-ignore-next-line convert-to-readonly, append-as-const
70
+ const mutableArray: number[] = [1, 2, 3];
70
71
 
71
72
  if (isArray(mutableArray)) {
72
- expectType<typeof mutableArray, readonly number[]>('=');
73
+ expectType<typeof mutableArray, number[]>('=');
73
74
 
74
75
  expect(mutableArray).toHaveLength(3);
75
76
  }
@@ -159,7 +160,7 @@ describe('Arr validations', () => {
159
160
  });
160
161
 
161
162
  test('should work as type guard (additional)', () => {
162
- const value: unknown = [1, 2, 3];
163
+ const value: unknown = [1, 2, 3] as const;
163
164
 
164
165
  if (isArray(value)) {
165
166
  expectType<typeof value, readonly unknown[]>('=');
@@ -169,14 +170,14 @@ describe('Arr validations', () => {
169
170
  });
170
171
 
171
172
  test('should handle array-like objects', () => {
172
- const arrayLike = { 0: 'a', 1: 'b', length: 2 };
173
+ const arrayLike = { 0: 'a', 1: 'b', length: 2 } as const;
173
174
 
174
175
  assert.isFalse(isArray(arrayLike));
175
176
  });
176
177
 
177
178
  describe('comprehensive type guard tests', () => {
178
179
  test('should narrow unknown type to array', () => {
179
- const value: unknown = [1, 2, 3];
180
+ const value: unknown = [1, 2, 3] as const;
180
181
 
181
182
  if (isArray(value)) {
182
183
  expectType<typeof value, readonly unknown[]>('=');
@@ -186,7 +187,7 @@ describe('Arr validations', () => {
186
187
  });
187
188
 
188
189
  test('should handle any type', () => {
189
- const value: any = [1, 2, 3];
190
+ const value: any = [1, 2, 3] as const;
190
191
 
191
192
  if (isArray(value)) {
192
193
  expectType<typeof value, readonly unknown[]>('=');
@@ -194,7 +195,7 @@ describe('Arr validations', () => {
194
195
  });
195
196
 
196
197
  test('should work with nested arrays', () => {
197
- const nested: readonly (readonly number[])[] = [[1], [2], [3]];
198
+ const nested: readonly (readonly number[])[] = [[1], [2], [3]] as const;
198
199
 
199
200
  if (isArray(nested)) {
200
201
  expectType<typeof nested, readonly (readonly number[])[]>('=');
@@ -202,7 +203,7 @@ describe('Arr validations', () => {
202
203
  });
203
204
 
204
205
  test('should distinguish between array and tuple types', () => {
205
- const tuple: readonly [1, 2, 3] = [1, 2, 3];
206
+ const tuple: readonly [1, 2, 3] = [1, 2, 3] as const;
206
207
 
207
208
  if (isArray(tuple)) {
208
209
  expectType<typeof tuple, readonly [1, 2, 3]>('=');
@@ -210,7 +211,7 @@ describe('Arr validations', () => {
210
211
  });
211
212
 
212
213
  test('should work with empty tuple type', () => {
213
- const emptyTuple: readonly [] = [];
214
+ const emptyTuple: readonly [] = [] as const;
214
215
 
215
216
  if (isArray(emptyTuple)) {
216
217
  expectType<typeof emptyTuple, readonly []>('=');
@@ -223,7 +224,7 @@ describe('Arr validations', () => {
223
224
  | readonly number[]
224
225
  | readonly boolean[];
225
226
 
226
- const mixedArray: MixedArrayUnion = [1, 2, 3];
227
+ const mixedArray: MixedArrayUnion = [1, 2, 3] as const;
227
228
 
228
229
  if (isArray(mixedArray)) {
229
230
  expectType<typeof mixedArray, MixedArrayUnion>('<=');
@@ -354,7 +355,11 @@ describe('Arr validations', () => {
354
355
  });
355
356
 
356
357
  test('should handle arrays with mixed element types', () => {
357
- const mixed: readonly (string | number | boolean)[] = [1, 'two', true];
358
+ const mixed: readonly (string | number | boolean)[] = [
359
+ 1,
360
+ 'two',
361
+ true,
362
+ ] as const;
358
363
 
359
364
  if (isArray(mixed)) {
360
365
  expectType<typeof mixed, readonly (string | number | boolean)[]>('=');
@@ -452,7 +457,7 @@ describe('Arr validations', () => {
452
457
  });
453
458
 
454
459
  test('should work with unknown readonly array type', () => {
455
- const arr: readonly number[] = [1, 2];
460
+ const arr: readonly number[] = [1, 2] as const;
456
461
 
457
462
  assert.isTrue(isArrayOfLength(arr, 2));
458
463
 
@@ -480,7 +485,7 @@ describe('Arr validations', () => {
480
485
  });
481
486
 
482
487
  test('should work as type guard with exact length (additional)', () => {
483
- const array: readonly number[] = [1, 2, 3];
488
+ const array: readonly number[] = [1, 2, 3] as const;
484
489
 
485
490
  if (isArrayOfLength(array, 3)) {
486
491
  expectType<typeof array, ArrayOfLength<3, number>>('=');
@@ -568,7 +573,7 @@ describe('Arr validations', () => {
568
573
  });
569
574
 
570
575
  test('should work as type guard for at least length (additional)', () => {
571
- const array: readonly number[] = [1, 2, 3];
576
+ const array: readonly number[] = [1, 2, 3] as const;
572
577
 
573
578
  if (isArrayAtLeastLength(array, 2)) {
574
579
  expectType<typeof array, ArrayAtLeastLen<2, number>>('=');
@@ -580,7 +585,7 @@ describe('Arr validations', () => {
580
585
 
581
586
  describe(every, () => {
582
587
  test('should return true when all elements satisfy predicate', () => {
583
- const evens = [2, 4, 6, 8];
588
+ const evens = [2, 4, 6, 8] as const;
584
589
 
585
590
  const allEven = every(evens, (n) => n % 2 === 0);
586
591
 
@@ -588,7 +593,7 @@ describe('Arr validations', () => {
588
593
  });
589
594
 
590
595
  test('should return false when not all elements satisfy predicate', () => {
591
- const mixed = [2, 3, 4, 6];
596
+ const mixed = [2, 3, 4, 6] as const;
592
597
 
593
598
  const allEven = every(mixed, (n) => n % 2 === 0);
594
599
 
@@ -596,7 +601,7 @@ describe('Arr validations', () => {
596
601
  });
597
602
 
598
603
  test('should work as type guard', () => {
599
- const mixed: readonly (string | number)[] = ['hello', 'world'];
604
+ const mixed: readonly (string | number)[] = ['hello', 'world'] as const;
600
605
 
601
606
  if (every(mixed, (x): x is string => typeof x === 'string')) {
602
607
  // TypeScript narrows mixed to readonly string[] here
@@ -619,7 +624,7 @@ describe('Arr validations', () => {
619
624
 
620
625
  const allStrings = every(isString);
621
626
 
622
- const data: readonly unknown[] = ['a', 'b', 'c'];
627
+ const data: readonly unknown[] = ['a', 'b', 'c'] as const;
623
628
 
624
629
  if (allStrings(data)) {
625
630
  // TypeScript narrows data to readonly string[] here
@@ -628,7 +633,7 @@ describe('Arr validations', () => {
628
633
  });
629
634
 
630
635
  test('should return true for empty array', () => {
631
- const empty: readonly number[] = [];
636
+ const empty: readonly number[] = [] as const;
632
637
 
633
638
  const result = every(empty, (n) => n > 0);
634
639
 
@@ -636,7 +641,7 @@ describe('Arr validations', () => {
636
641
  });
637
642
 
638
643
  test('should pass index to predicate', () => {
639
- const numbers = [0, 1, 2, 3];
644
+ const numbers = [0, 1, 2, 3] as readonly number[];
640
645
 
641
646
  const indexMatchesValue = every(numbers, (val, idx) => val === idx);
642
647
 
@@ -646,7 +651,7 @@ describe('Arr validations', () => {
646
651
 
647
652
  describe(some, () => {
648
653
  test('should return true when at least one element satisfies predicate', () => {
649
- const numbers = [1, 3, 5, 8];
654
+ const numbers = [1, 3, 5, 8] as const;
650
655
 
651
656
  const hasEven = some(numbers, (n) => n % 2 === 0);
652
657
 
@@ -654,7 +659,7 @@ describe('Arr validations', () => {
654
659
  });
655
660
 
656
661
  test('should return false when no elements satisfy predicate', () => {
657
- const odds = [1, 3, 5, 7];
662
+ const odds = [1, 3, 5, 7] as const;
658
663
 
659
664
  const hasEven = some(odds, (n) => n % 2 === 0);
660
665
 
@@ -672,7 +677,7 @@ describe('Arr validations', () => {
672
677
  });
673
678
 
674
679
  test('should return false for empty array', () => {
675
- const empty: readonly number[] = [];
680
+ const empty: readonly number[] = [] as const;
676
681
 
677
682
  const result = some(empty, (n) => n > 0);
678
683
 
@@ -680,7 +685,7 @@ describe('Arr validations', () => {
680
685
  });
681
686
 
682
687
  test('should pass index to predicate', () => {
683
- const numbers = [10, 10, 10, 30];
688
+ const numbers = [10, 10, 10, 30] as const;
684
689
 
685
690
  const hasValueMatchingIndex = some(
686
691
  numbers,
@@ -693,7 +698,7 @@ describe('Arr validations', () => {
693
698
 
694
699
  describe(indexIsInRange, () => {
695
700
  test('should return true for valid indices', () => {
696
- const array = ['a', 'b', 'c'];
701
+ const array = ['a', 'b', 'c'] as const;
697
702
 
698
703
  assert.isTrue(indexIsInRange(array, 0));
699
704
 
@@ -703,7 +708,7 @@ describe('Arr validations', () => {
703
708
  });
704
709
 
705
710
  test('should return false for invalid indices', () => {
706
- const array = ['a', 'b', 'c'];
711
+ const array = ['a', 'b', 'c'] as const;
707
712
 
708
713
  assert.isFalse(indexIsInRange(array, 3));
709
714
 
@@ -711,7 +716,7 @@ describe('Arr validations', () => {
711
716
  });
712
717
 
713
718
  test('should work with empty array', () => {
714
- const empty: readonly string[] = [];
719
+ const empty: readonly string[] = [] as const;
715
720
 
716
721
  assert.isFalse(indexIsInRange(empty, 0));
717
722
 
@@ -720,7 +725,7 @@ describe('Arr validations', () => {
720
725
  });
721
726
 
722
727
  test('should be type error with floating point indices', () => {
723
- const array = [1, 2, 3];
728
+ const array = [1, 2, 3] as const;
724
729
 
725
730
  // @ts-expect-error floating point indices should not be allowed
726
731
  assert.isTrue(indexIsInRange(array, 1.5)); // JavaScript arrays accept floating point indices
@@ -60,7 +60,7 @@ describe('Array.includes', () => {
60
60
  }
61
61
 
62
62
  {
63
- const xs: readonly number[] = [2, 1, 3];
63
+ const xs: readonly number[] = [2, 1, 3] as const;
64
64
 
65
65
  const result = xs.includes(4);
66
66
 
@@ -56,21 +56,15 @@ type IMapMappedInterface<K, V, KM extends MapSetKeyType> = Readonly<{
56
56
  // Reducing a value
57
57
 
58
58
  /**
59
- * Checks if all elements in the map satisfy a predicate.
59
+ * Checks if all elements in the map satisfy a predicate. Also supports a
60
+ * type predicate overload that narrows the type of values in the map if the
61
+ * predicate returns true for all elements.
60
62
  *
63
+ * @template W The narrowed type of the values.
61
64
  * @param predicate A function to test each key-value pair.
62
65
  * @returns `true` if all elements satisfy the predicate, `false` otherwise.
63
66
  */
64
67
  every: ((predicate: (value: V, key: K) => boolean) => boolean) &
65
- /**
66
- * Checks if all elements in the map satisfy a type predicate. Narrows the
67
- * type of values in the map if the predicate returns true for all
68
- * elements.
69
- *
70
- * @template W The narrowed type of the values.
71
- * @param predicate A type predicate function.
72
- * @returns `true` if all elements satisfy the predicate, `false` otherwise.
73
- */
74
68
  (<W extends V>(
75
69
  predicate: (value: V, key: K) => value is W,
76
70
  ) => this is IMapMapped<K, W, KM>);
@@ -3,12 +3,12 @@ import { IMapMapped } from './imap-mapped.mjs';
3
3
 
4
4
  const toKey = (a: Readonly<{ v: number }>): number => a.v;
5
5
 
6
- const fromKey = (k: number): Readonly<{ v: number }> => ({ v: k });
6
+ const fromKey = (k: number): Readonly<{ v: number }> => ({ v: k }) as const;
7
7
 
8
8
  type TestKey = Readonly<{ id: number; type: string }>;
9
9
 
10
10
  const testKeyToString = (key: Readonly<TestKey>): string =>
11
- `${key.type}_${key.id}`;
11
+ `${key.type}_${key.id}` as const;
12
12
 
13
13
  const stringToTestKey = (str: string): TestKey => {
14
14
  const [type, idStr] = str.split('_');
@@ -105,7 +105,7 @@ describe('IMapMapped.create', () => {
105
105
  nested: { id: number };
106
106
  arr: number[];
107
107
  }>,
108
- ): string => `${key.nested.id}_${key.arr.join(',')}`;
108
+ ): string => `${key.nested.id}_${key.arr.join(',')}` as const;
109
109
 
110
110
  const stringToComplexKey = (str: string): ComplexKey => {
111
111
  const [idStr, arrStr] = str.split('_');
@@ -777,9 +777,9 @@ describe('IMapMapped.forEach', () => {
777
777
  fromKey,
778
778
  );
779
779
 
780
- const keys = [{ v: 1 }, { v: 2 }, { v: 3 }];
780
+ const keys = [{ v: 1 }, { v: 2 }, { v: 3 }] as const;
781
781
 
782
- const values = ['1', '2', '3'];
782
+ const values = ['1', '2', '3'] as const;
783
783
 
784
784
  for (const [key, value] of s0.entries()) {
785
785
  expect(keys).toContainEqual(key);
@@ -824,7 +824,7 @@ describe('IMapMapped.keys', () => {
824
824
  fromKey,
825
825
  );
826
826
 
827
- const keys = [{ v: 1 }, { v: 2 }, { v: 3 }];
827
+ const keys = [{ v: 1 }, { v: 2 }, { v: 3 }] as const;
828
828
 
829
829
  for (const k of s0.keys()) {
830
830
  expect(keys).toContainEqual(k);
@@ -844,7 +844,7 @@ describe('IMapMapped.values', () => {
844
844
  fromKey,
845
845
  );
846
846
 
847
- const values = ['1', '2', '3'];
847
+ const values = ['1', '2', '3'] as const;
848
848
 
849
849
  for (const v of s0.values()) {
850
850
  expect(values).toContainEqual(v);
@@ -864,9 +864,9 @@ describe('IMapMapped.entries', () => {
864
864
  fromKey,
865
865
  );
866
866
 
867
- const keys = [{ v: 1 }, { v: 2 }, { v: 3 }];
867
+ const keys = [{ v: 1 }, { v: 2 }, { v: 3 }] as const;
868
868
 
869
- const values = ['1', '2', '3'];
869
+ const values = ['1', '2', '3'] as const;
870
870
 
871
871
  for (const [k, v] of s0.entries()) {
872
872
  expect(keys).toContainEqual(k);
@@ -40,7 +40,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
40
40
  * const entries = [
41
41
  * ['a', 1],
42
42
  * ['b', 2],
43
- * ] satisfies readonly (readonly [string, number])[];
43
+ * ] as const satisfies readonly (readonly [string, number])[];
44
44
  *
45
45
  * const map = IMap.create(entries);
46
46
  *
@@ -93,7 +93,9 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
93
93
  // Reducing a value
94
94
 
95
95
  /**
96
- * Checks if all elements in the map satisfy a predicate.
96
+ * Checks if all elements in the map satisfy a predicate. Also supports a
97
+ * type predicate overload that narrows the type of values in the map if the
98
+ * predicate returns true for all elements.
97
99
  *
98
100
  * @example
99
101
  *
@@ -112,19 +114,11 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
112
114
  * assert.isTrue(isNarrowed);
113
115
  * ```
114
116
  *
117
+ * @template W The narrowed type of the values.
115
118
  * @param predicate A function to test each key-value pair.
116
119
  * @returns `true` if all elements satisfy the predicate, `false` otherwise.
117
120
  */
118
121
  every: ((predicate: (value: V, key: K) => boolean) => boolean) &
119
- /**
120
- * Checks if all elements in the map satisfy a type predicate. Narrows the
121
- * type of values in the map if the predicate returns true for all
122
- * elements.
123
- *
124
- * @template W The narrowed type of the values.
125
- * @param predicate A type predicate function.
126
- * @returns `true` if all elements satisfy the predicate, `false` otherwise.
127
- */
128
122
  (<W extends V>(
129
123
  predicate: (value: V, key: K) => value is W,
130
124
  ) => this is IMap<K, W>);
@@ -138,7 +132,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
138
132
  * const entries = [
139
133
  * ['alice', 3],
140
134
  * ['bob', 5],
141
- * ] satisfies readonly (readonly [string, number])[];
135
+ * ] as const satisfies readonly (readonly [string, number])[];
142
136
  *
143
137
  * const map = IMap.create(entries);
144
138
  *
@@ -188,7 +182,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
188
182
  * @example
189
183
  *
190
184
  * ```ts
191
- * const entries = [['count', 1]] satisfies readonly (readonly [
185
+ * const entries = [['count', 1]] as const satisfies readonly (readonly [
192
186
  * 'count' | 'status',
193
187
  * number | string,
194
188
  * ])[];
@@ -221,7 +215,10 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
221
215
  * const entries = [
222
216
  * ['alice', 10],
223
217
  * ['bob', 8],
224
- * ] satisfies readonly (readonly ['alice' | 'bob' | 'charlie', number])[];
218
+ * ] as const satisfies readonly (readonly [
219
+ * 'alice' | 'bob' | 'charlie',
220
+ * number,
221
+ * ])[];
225
222
  *
226
223
  * const scores = IMap.create<'alice' | 'bob' | 'charlie', number>(entries);
227
224
  *
@@ -252,7 +249,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
252
249
  * const entries = [
253
250
  * ['a', 1],
254
251
  * ['b', 2],
255
- * ] satisfies readonly (readonly ['a' | 'b' | 'c', number])[];
252
+ * ] as const satisfies readonly (readonly ['a' | 'b' | 'c', number])[];
256
253
  *
257
254
  * const base = IMap.create<'a' | 'b' | 'c', number>(entries);
258
255
  *
@@ -264,7 +261,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
264
261
  * { type: 'set', key: 'c', value: 3 },
265
262
  * { type: 'update', key: 'b', updater: (value) => value * 10 },
266
263
  * { type: 'delete', key: 'a' },
267
- * ];
264
+ * ] as const;
268
265
  *
269
266
  * const mutated = base.withMutations(actions);
270
267
  *
@@ -299,7 +296,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
299
296
  * const entries = [
300
297
  * ['a', 1],
301
298
  * ['b', 2],
302
- * ] satisfies readonly (readonly [string, number])[];
299
+ * ] as const satisfies readonly (readonly [string, number])[];
303
300
  *
304
301
  * const map = IMap.create(entries);
305
302
  *
@@ -326,7 +323,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
326
323
  * const entries = [
327
324
  * ['first', 1],
328
325
  * ['second', 2],
329
- * ] satisfies readonly (readonly [string, number])[];
326
+ * ] as const satisfies readonly (readonly [string, number])[];
330
327
  *
331
328
  * const map = IMap.create(entries);
332
329
  *
@@ -353,7 +350,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
353
350
  * const entries = [
354
351
  * ['a', 1],
355
352
  * ['b', 2],
356
- * ] satisfies readonly (readonly [string, number])[];
353
+ * ] as const satisfies readonly (readonly [string, number])[];
357
354
  *
358
355
  * const map = IMap.create(entries);
359
356
  *
@@ -416,7 +413,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
416
413
  * const entries = [
417
414
  * ['a', 1],
418
415
  * ['b', 2],
419
- * ] satisfies readonly (readonly [string, number])[];
416
+ * ] as const satisfies readonly (readonly [string, number])[];
420
417
  *
421
418
  * const map = IMap.create(entries);
422
419
  *
@@ -438,7 +435,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
438
435
  * const entries = [
439
436
  * ['a', 1],
440
437
  * ['b', 2],
441
- * ] satisfies readonly (readonly [string, number])[];
438
+ * ] as const satisfies readonly (readonly [string, number])[];
442
439
  *
443
440
  * const map = IMap.create(entries);
444
441
  *
@@ -485,7 +482,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
485
482
  * const entries = [
486
483
  * ['x', 10],
487
484
  * ['y', 20],
488
- * ] satisfies readonly (readonly [string, number])[];
485
+ * ] as const satisfies readonly (readonly [string, number])[];
489
486
  *
490
487
  * const map = IMap.create(entries);
491
488
  *
@@ -505,7 +502,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
505
502
  * const entries = [
506
503
  * ['x', 10],
507
504
  * ['y', 20],
508
- * ] satisfies readonly (readonly [string, number])[];
505
+ * ] as const satisfies readonly (readonly [string, number])[];
509
506
  *
510
507
  * const map = IMap.create(entries);
511
508
  *
@@ -525,7 +522,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
525
522
  * const entries = [
526
523
  * ['a', 1],
527
524
  * ['b', 2],
528
- * ] satisfies readonly (readonly [string, number])[];
525
+ * ] as const satisfies readonly (readonly [string, number])[];
529
526
  *
530
527
  * const map = IMap.create(entries);
531
528
  *
@@ -549,7 +546,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
549
546
  * const entries = [
550
547
  * ['k1', 'v1'],
551
548
  * ['k2', 'v2'],
552
- * ] satisfies readonly (readonly [string, string])[];
549
+ * ] as const satisfies readonly (readonly [string, string])[];
553
550
  *
554
551
  * const map = IMap.create(entries);
555
552
  *
@@ -569,7 +566,7 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
569
566
  * @example
570
567
  *
571
568
  * ```ts
572
- * const entries = [['key', 1]] satisfies readonly (readonly [
569
+ * const entries = [['key', 1]] as const satisfies readonly (readonly [
573
570
  * string,
574
571
  * number,
575
572
  * ])[];
@@ -922,7 +919,7 @@ class IMapClass<K extends MapSetKeyType, V>
922
919
  * const entries = [
923
920
  * ['first', 1],
924
921
  * ['second', 2],
925
- * ] satisfies readonly (readonly [string, number])[];
922
+ * ] as const satisfies readonly (readonly [string, number])[];
926
923
  *
927
924
  * const map = IMap.create(entries);
928
925
  *
@@ -878,9 +878,9 @@ describe('IMap.forEach', () => {
878
878
  [7, 70],
879
879
  ] as const);
880
880
 
881
- const keys = [1, 3, 5, 6, 7];
881
+ const keys = [1, 3, 5, 6, 7] as const;
882
882
 
883
- const values = [10, 30, 50, 60, 70];
883
+ const values = [10, 30, 50, 60, 70] as const;
884
884
 
885
885
  for (const [key, value] of m0.entries()) {
886
886
  expect(keys).toContain(key);
@@ -935,7 +935,7 @@ describe('IMap.keys', () => {
935
935
  [7, 70],
936
936
  ] as const);
937
937
 
938
- const keys = [1, 3, 5, 6, 7];
938
+ const keys = [1, 3, 5, 6, 7] as const;
939
939
 
940
940
  for (const k of m0.keys()) {
941
941
  expect(keys).toContain(k);
@@ -953,7 +953,7 @@ describe('IMap.values', () => {
953
953
  [7, 70],
954
954
  ]);
955
955
 
956
- const values = [10, 30, 50, 60, 70];
956
+ const values = [10, 30, 50, 60, 70] as const;
957
957
 
958
958
  for (const v of m0.values()) {
959
959
  expect(values).toContain(v);
@@ -971,9 +971,9 @@ describe('IMap.entries', () => {
971
971
  [7, 70],
972
972
  ]);
973
973
 
974
- const keys = [1, 3, 5, 6, 7];
974
+ const keys = [1, 3, 5, 6, 7] as const;
975
975
 
976
- const values = [10, 30, 50, 60, 70];
976
+ const values = [10, 30, 50, 60, 70] as const;
977
977
 
978
978
  for (const [k, v] of m0.entries()) {
979
979
  expect(keys).toContain(k);
@@ -60,7 +60,7 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
60
60
  * const points: readonly Point[] = [
61
61
  * { x: 1, tag: 'a' },
62
62
  * { x: 2, tag: 'b' },
63
- * ];
63
+ * ] as const;
64
64
  *
65
65
  * const set = ISetMapped.create<Point, string>(points, toKey, fromKey);
66
66
  *
@@ -129,7 +129,10 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
129
129
  // Reducing a value
130
130
 
131
131
  /**
132
- * Checks if all elements in the set satisfy a predicate.
132
+ * Checks if all elements in the set satisfy a type predicate. Narrows the
133
+ * type of elements in the set if the predicate returns true for all
134
+ * elements.
135
+ *
133
136
  *
134
137
  * @example
135
138
  *
@@ -162,19 +165,11 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
162
165
  * assert.isTrue(narrowed);
163
166
  * ```
164
167
  *
168
+ * @template L The narrowed type of the elements.
165
169
  * @param predicate A function to test each element.
166
170
  * @returns `true` if all elements satisfy the predicate, `false` otherwise.
167
171
  */
168
172
  every: ((predicate: (key: K) => boolean) => boolean) &
169
- /**
170
- * Checks if all elements in the set satisfy a type predicate. Narrows the
171
- * type of elements in the set if the predicate returns true for all
172
- * elements.
173
- *
174
- * @template L The narrowed type of the elements.
175
- * @param predicate A type predicate function.
176
- * @returns `true` if all elements satisfy the predicate, `false` otherwise.
177
- */
178
173
  (<L extends K>(
179
174
  predicate: (key: K) => key is L,
180
175
  ) => this is ISetMapped<L, KM>);
@@ -313,7 +308,7 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
313
308
  * >[] = [
314
309
  * { type: 'add', key: { x: 3, tag: 'c' } },
315
310
  * { type: 'delete', key: { x: 1, tag: 'a' } },
316
- * ];
311
+ * ] as const;
317
312
  *
318
313
  * const mutated = base.withMutations(actions);
319
314
  *
@@ -1056,10 +1051,11 @@ export namespace ISetMapped {
1056
1051
  export const diff = <K, KM extends MapSetKeyType>(
1057
1052
  oldSet: ISetMapped<K, KM>,
1058
1053
  newSet: ISetMapped<K, KM>,
1059
- ): ReadonlyRecord<'added' | 'deleted', ISetMapped<K, KM>> => ({
1060
- deleted: oldSet.subtract(newSet),
1061
- added: newSet.subtract(oldSet),
1062
- });
1054
+ ): ReadonlyRecord<'added' | 'deleted', ISetMapped<K, KM>> =>
1055
+ ({
1056
+ deleted: oldSet.subtract(newSet),
1057
+ added: newSet.subtract(oldSet),
1058
+ }) as const;
1063
1059
 
1064
1060
  /**
1065
1061
  * Computes the intersection of two ISetMapped instances.