ts-data-forge 1.5.2 → 2.0.1

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 (41) hide show
  1. package/README.md +56 -44
  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/functional/pipe.d.mts +56 -61
  15. package/dist/functional/pipe.d.mts.map +1 -1
  16. package/dist/functional/pipe.mjs.map +1 -1
  17. package/dist/globals.d.mts +10 -9
  18. package/dist/index.mjs +0 -1
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/json/json.mjs +0 -1
  21. package/dist/json/json.mjs.map +1 -1
  22. package/dist/number/num.d.mts +1 -1
  23. package/package.json +2 -2
  24. package/src/array/array-utils-modification.test.mts +93 -67
  25. package/src/array/array-utils-overload-type-error.test.mts +2 -2
  26. package/src/array/array-utils-reducing-value.test.mts +31 -37
  27. package/src/array/array-utils-slice-clamped.test.mts +94 -70
  28. package/src/array/array-utils-transformation.test.mts +557 -10
  29. package/src/array/array-utils.mts +1457 -516
  30. package/src/array/index.mts +0 -1
  31. package/src/collections/queue.mts +2 -2
  32. package/src/collections/stack.mts +8 -8
  33. package/src/functional/pipe.mts +65 -75
  34. package/src/globals.d.mts +10 -9
  35. package/src/number/num.mts +1 -1
  36. package/dist/array/tuple-utils.d.mts +0 -407
  37. package/dist/array/tuple-utils.d.mts.map +0 -1
  38. package/dist/array/tuple-utils.mjs +0 -345
  39. package/dist/array/tuple-utils.mjs.map +0 -1
  40. package/src/array/tuple-utils.mts +0 -498
  41. package/src/array/tuple-utils.test.mts +0 -518
@@ -7,7 +7,7 @@ describe('Arr modifications', () => {
7
7
  const xs = [1, 2, 3] as const;
8
8
  const result = Arr.toUpdated(xs, 1, (x) => x + 2);
9
9
 
10
- expectType<typeof result, readonly number[]>('=');
10
+ expectType<typeof result, ArrayOfLength<3, number>>('=');
11
11
 
12
12
  test('case 1', () => {
13
13
  expect(result).toStrictEqual([1, 4, 3]);
@@ -17,112 +17,107 @@ describe('Arr modifications', () => {
17
17
  describe('toInserted', () => {
18
18
  const xs = [1, 2, 3] as const;
19
19
 
20
- {
20
+ test('case 1', () => {
21
21
  const result = Arr.toInserted(xs, 1, 5);
22
22
 
23
- expectType<typeof result, NonEmptyArray<1 | 2 | 3 | 5>>('=');
23
+ expectType<typeof result, ArrayOfLength<4, 1 | 2 | 3 | 5>>('=');
24
24
 
25
- test('case 1', () => {
26
- expect(result).toStrictEqual([1, 5, 2, 3]);
27
- });
28
- }
29
- {
30
- const result = Arr.toInserted(xs, 0, 5);
25
+ expect(result).toStrictEqual([1, 5, 2, 3]);
26
+ });
31
27
 
32
- expectType<typeof result, NonEmptyArray<1 | 2 | 3 | 5>>('=');
28
+ test('case 2 (insert head)', () => {
29
+ const result = Arr.toInserted(xs, 0, 5);
33
30
 
34
- test('case 2 (insert head)', () => {
35
- expect(result).toStrictEqual([5, 1, 2, 3]);
36
- });
37
- }
38
- {
39
- const result = Arr.toInserted(xs, 3, 5);
31
+ expectType<typeof result, ArrayOfLength<4, 1 | 2 | 3 | 5>>('=');
40
32
 
41
- expectType<typeof result, NonEmptyArray<1 | 2 | 3 | 5>>('=');
33
+ expect(result).toStrictEqual([5, 1, 2, 3]);
34
+ });
42
35
 
43
- test('case 3 (insert tail)', () => {
44
- expect(result).toStrictEqual([1, 2, 3, 5]);
45
- });
46
- }
47
- {
48
- const result = Arr.toInserted(xs, asUint32(999), 5);
36
+ test('case 3 (insert tail)', () => {
37
+ const result = Arr.toInserted(['a', 'b', 'c'], asUint32(999), 5);
49
38
 
50
- expectType<typeof result, NonEmptyArray<1 | 2 | 3 | 5>>('=');
39
+ expectType<typeof result, NonEmptyArray<string | 5>>('=');
51
40
 
52
- test('case 4 (insert tail)', () => {
53
- expect(result).toStrictEqual([1, 2, 3, 5]);
54
- });
55
- }
41
+ expect(result).toStrictEqual(['a', 'b', 'c', 5]);
42
+ });
56
43
  });
57
44
 
58
45
  describe('toRemoved', () => {
59
- const xs = [1, 2, 3] as const;
60
-
61
- {
46
+ test('case 1', () => {
47
+ const xs = [1, 2, 3] as const;
62
48
  const result = Arr.toRemoved(xs, 1);
63
49
 
64
50
  expectType<typeof result, readonly (1 | 2 | 3)[]>('=');
65
51
 
66
- test('case 1', () => {
67
- expect(result).toStrictEqual([1, 3]);
68
- });
69
- }
70
- {
52
+ expect(result).toStrictEqual([1, 3]);
53
+ });
54
+
55
+ test('case 2 (remove head)', () => {
56
+ const xs = [1, 2, 3] as const;
71
57
  const result = Arr.toRemoved(xs, 0);
72
58
 
73
59
  expectType<typeof result, readonly (1 | 2 | 3)[]>('=');
74
60
 
75
- test('case 2 (remove head)', () => {
76
- expect(result).toStrictEqual([2, 3]);
77
- });
78
- }
79
- {
61
+ expect(result).toStrictEqual([2, 3]);
62
+ });
63
+
64
+ test('case 3 (remove tail)', () => {
65
+ const xs = [1, 2, 3] as const;
80
66
  const result = Arr.toRemoved(xs, 2);
81
67
 
82
68
  expectType<typeof result, readonly (1 | 2 | 3)[]>('=');
83
69
 
84
- test('case 3 (remove tail)', () => {
85
- expect(result).toStrictEqual([1, 2]);
86
- });
87
- }
88
- {
89
- const result = Arr.toRemoved(xs, 3);
90
-
91
- expectType<typeof result, readonly (1 | 2 | 3)[]>('=');
70
+ expect(result).toStrictEqual([1, 2]);
71
+ });
92
72
 
93
- test('case 3 (noop)', () => {
94
- expect(result).toStrictEqual([1, 2, 3]);
95
- });
96
- }
97
- {
73
+ test('case 4 (number[])', () => {
74
+ const xs: number[] = [1, 2, 3];
98
75
  const result = Arr.toRemoved(xs, 5);
99
76
 
100
- expectType<typeof result, readonly (1 | 2 | 3)[]>('=');
77
+ expectType<typeof result, readonly number[]>('=');
101
78
 
102
- test('case 4 (noop)', () => {
103
- expect(result).toStrictEqual([1, 2, 3]);
104
- });
105
- }
79
+ expect(result).toStrictEqual([1, 2, 3]);
80
+ });
106
81
  });
107
82
 
108
83
  describe('toPushed', () => {
109
- const xs = [1, 2, 3] as const;
110
- const result = Arr.toPushed(xs, 4 as const);
84
+ test('case 1', () => {
85
+ const xs = [1, 2, 3] as const;
86
+ const result = Arr.toPushed(xs, 4 as const);
111
87
 
112
- expectType<typeof result, readonly [1, 2, 3, 4]>('=');
88
+ expectType<typeof result, readonly [1, 2, 3, 4]>('=');
89
+
90
+ expect(result).toStrictEqual([1, 2, 3, 4]);
91
+ });
92
+
93
+ test('case 2', () => {
94
+ const xs: number[] = [1, 2, 3];
95
+ const result = Arr.toPushed(xs, 4 as const);
96
+
97
+ expectType<typeof result, readonly [...number[], 4]>('=');
113
98
 
114
- test('case 1', () => {
115
99
  expect(result).toStrictEqual([1, 2, 3, 4]);
116
100
  });
117
101
  });
118
102
 
119
103
  describe('toUnshifted', () => {
120
- const xs = [1, 2, 3] as const;
121
- const result = Arr.toUnshifted(xs, 4 as const);
104
+ test('case 1', () => {
105
+ const xs = [1, 2, 3] as const;
122
106
 
123
- expectType<typeof result, readonly [4, 1, 2, 3]>('=');
107
+ const result = Arr.toUnshifted(xs, 4 as const);
108
+
109
+ expectType<typeof result, readonly [4, 1, 2, 3]>('=');
110
+
111
+ expect(result).toStrictEqual([4, 1, 2, 3]);
112
+ });
113
+
114
+ test('case 2', () => {
115
+ const xs: number[] = [1, 2, 3];
116
+
117
+ const result = Arr.toUnshifted(xs, 4 as const);
118
+
119
+ expectType<typeof result, readonly [4, ...number[]]>('=');
124
120
 
125
- test('case 1', () => {
126
121
  expect(result).toStrictEqual([4, 1, 2, 3]);
127
122
  });
128
123
  });
@@ -194,4 +189,35 @@ describe('Arr modifications', () => {
194
189
  expect(Arr.toRangeFilled(arr, 0, [1, 2.5])).toStrictEqual([1, 0, 3]);
195
190
  });
196
191
  });
192
+
193
+ describe('set', () => {
194
+ const result = Arr.set([1, 2, 3], 1, 4);
195
+
196
+ expectType<typeof result, readonly [1 | 4, 2 | 4, 3 | 4]>('=');
197
+
198
+ test('case 1', () => {
199
+ expect(result).toStrictEqual([1, 4, 3]);
200
+ });
201
+
202
+ test('should work with different value types', () => {
203
+ const nums = [1, 2, 3] as const;
204
+ const withString = Arr.set(nums, 1, 'two');
205
+ expectType<typeof withString, readonly [1 | 'two', 2 | 'two', 3 | 'two']>(
206
+ '=',
207
+ );
208
+ expect(withString).toStrictEqual([1, 'two', 3]);
209
+ });
210
+
211
+ test('should work at index 0', () => {
212
+ const tuple = ['a', 'b', 'c'] as const;
213
+ const updated = Arr.set(tuple, 0, 'A');
214
+ expect(updated).toStrictEqual(['A', 'b', 'c']);
215
+ });
216
+
217
+ test('should work at last index', () => {
218
+ const tuple = ['a', 'b', 'c'] as const;
219
+ const updated = Arr.set(tuple, 2, 'C');
220
+ expect(updated).toStrictEqual(['a', 'b', 'C']);
221
+ });
222
+ });
197
223
  });
@@ -15,7 +15,7 @@ describe('Array overloaded functions - type error validation', () => {
15
15
  const _result2 = Arr.findIndex(predicate);
16
16
  const _result3 = Arr.findIndex(predicate)(testArray);
17
17
 
18
- expectType<typeof _result1, SizeType.Arr | -1>('=');
18
+ expectType<typeof _result1, 0 | 1 | 2 | 3 | 4 | -1>('=');
19
19
  expectType<
20
20
  typeof _result2,
21
21
  (array: readonly number[]) => SizeType.Arr | -1
@@ -113,7 +113,7 @@ describe('Array overloaded functions - type error validation', () => {
113
113
  const _result1 = Arr.findIndex(...correctArgs1);
114
114
  const _result2 = Arr.findIndex(...correctArgs2);
115
115
 
116
- expectType<typeof _result1, SizeType.Arr | -1>('<=');
116
+ expectType<typeof _result1, 0 | 1 | 2 | 3 | 4 | -1>('<=');
117
117
  expectType<
118
118
  typeof _result2,
119
119
  (array: readonly number[]) => SizeType.Arr | -1
@@ -87,14 +87,7 @@ describe('Arr reducing value', () => {
87
87
  });
88
88
 
89
89
  describe('minBy', () => {
90
- const xs: NonEmptyArray<
91
- | Readonly<{ x: 1; y: 2 }>
92
- | Readonly<{ x: 2; y: 3 }>
93
- | Readonly<{ x: 3; y: 2 }>
94
- | Readonly<{ x: 4; y: 1 }>
95
- | Readonly<{ x: 5; y: 1 }>
96
- | Readonly<{ x: 6; y: 1 }>
97
- > = [
90
+ const xs = [
98
91
  { x: 5, y: 1 },
99
92
  { x: 4, y: 1 },
100
93
  { x: 6, y: 1 },
@@ -108,12 +101,14 @@ describe('Arr reducing value', () => {
108
101
  expectType<
109
102
  typeof result,
110
103
  Optional.Some<
111
- | Readonly<{ x: 1; y: 2 }>
112
- | Readonly<{ x: 2; y: 3 }>
113
- | Readonly<{ x: 3; y: 2 }>
114
- | Readonly<{ x: 4; y: 1 }>
115
- | Readonly<{ x: 5; y: 1 }>
116
- | Readonly<{ x: 6; y: 1 }>
104
+ Readonly<
105
+ | { x: 1; y: 2 }
106
+ | { x: 2; y: 3 }
107
+ | { x: 3; y: 2 }
108
+ | { x: 4; y: 1 }
109
+ | { x: 5; y: 1 }
110
+ | { x: 6; y: 1 }
111
+ >
117
112
  >
118
113
  >('=');
119
114
 
@@ -146,10 +141,12 @@ describe('Arr reducing value', () => {
146
141
 
147
142
  expectType<
148
143
  typeof res,
149
- Optional<
150
- | Readonly<{ name: 'apple'; score: 10 }>
151
- | Readonly<{ name: 'banana'; score: 5 }>
152
- | Readonly<{ name: 'cherry'; score: 12 }>
144
+ Optional.Some<
145
+ Readonly<
146
+ | { name: 'apple'; score: 10 }
147
+ | { name: 'banana'; score: 5 }
148
+ | { name: 'cherry'; score: 12 }
149
+ >
153
150
  >
154
151
  >('=');
155
152
 
@@ -161,14 +158,7 @@ describe('Arr reducing value', () => {
161
158
  });
162
159
 
163
160
  describe('maxBy', () => {
164
- const xs: NonEmptyArray<
165
- | Readonly<{ x: 1; y: 2 }>
166
- | Readonly<{ x: 2; y: 3 }>
167
- | Readonly<{ x: 3; y: 2 }>
168
- | Readonly<{ x: 4; y: 1 }>
169
- | Readonly<{ x: 5; y: 1 }>
170
- | Readonly<{ x: 6; y: 1 }>
171
- > = [
161
+ const xs = [
172
162
  { x: 5, y: 1 },
173
163
  { x: 4, y: 1 },
174
164
  { x: 6, y: 1 },
@@ -182,12 +172,14 @@ describe('Arr reducing value', () => {
182
172
  expectType<
183
173
  typeof result,
184
174
  Optional.Some<
185
- | Readonly<{ x: 1; y: 2 }>
186
- | Readonly<{ x: 2; y: 3 }>
187
- | Readonly<{ x: 3; y: 2 }>
188
- | Readonly<{ x: 4; y: 1 }>
189
- | Readonly<{ x: 5; y: 1 }>
190
- | Readonly<{ x: 6; y: 1 }>
175
+ Readonly<
176
+ | { x: 1; y: 2 }
177
+ | { x: 2; y: 3 }
178
+ | { x: 3; y: 2 }
179
+ | { x: 4; y: 1 }
180
+ | { x: 5; y: 1 }
181
+ | { x: 6; y: 1 }
182
+ >
191
183
  >
192
184
  >('=');
193
185
 
@@ -220,10 +212,12 @@ describe('Arr reducing value', () => {
220
212
 
221
213
  expectType<
222
214
  typeof res,
223
- Optional<
224
- | Readonly<{ name: 'apple'; score: 10 }>
225
- | Readonly<{ name: 'banana'; score: 5 }>
226
- | Readonly<{ name: 'cherry'; score: 12 }>
215
+ Optional.Some<
216
+ Readonly<
217
+ | { name: 'apple'; score: 10 }
218
+ | { name: 'banana'; score: 5 }
219
+ | { name: 'cherry'; score: 12 }
220
+ >
227
221
  >
228
222
  >('=');
229
223
 
@@ -272,7 +266,7 @@ describe('Arr reducing value', () => {
272
266
 
273
267
  const result = Arr.countBy(xs, (a) => a.x);
274
268
 
275
- expectType<typeof result, IMap<1 | 2 | 3, Uint32>>('=');
269
+ expectType<typeof result, IMap<1 | 2 | 3, 0 | 1 | 2 | 3 | 4 | 5>>('=');
276
270
 
277
271
  test('case 1', () => {
278
272
  expect(result).toStrictEqual(
@@ -3,81 +3,105 @@ import { Arr } from './array-utils.mjs';
3
3
 
4
4
  describe('Arr', () => {
5
5
  describe('sliceClamped', () => {
6
- const list = [0, 1, 2, 3, 4] as const;
6
+ {
7
+ const list: readonly number[] = [0, 1, 2, 3, 4] as const;
7
8
 
8
- test.each([
9
- {
10
- start: 0,
11
- end: 5,
12
- expected: [0, 1, 2, 3, 4],
13
- }, // normal
14
- {
15
- start: 0,
16
- end: 6,
17
- expected: [0, 1, 2, 3, 4],
18
- }, // one side overflow
19
- {
20
- start: -1,
21
- end: 5,
22
- expected: [0, 1, 2, 3, 4],
23
- }, // one side overflow
24
- {
25
- start: -1,
26
- end: 6,
27
- expected: [0, 1, 2, 3, 4],
28
- }, // both sides overflow
29
- {
30
- start: 0,
31
- end: 3,
32
- expected: [0, 1, 2],
33
- }, // normal
34
- {
35
- start: 1,
36
- end: 3,
37
- expected: [1, 2],
38
- }, // normal
39
- {
40
- start: -1,
41
- end: 3,
42
- expected: [0, 1, 2],
43
- }, // one side overflow
44
- {
45
- start: 3,
46
- end: 5,
47
- expected: [3, 4],
48
- }, // normal
49
- {
50
- start: 3,
51
- end: 6,
52
- expected: [3, 4],
53
- }, // one side overflow
54
- {
55
- start: 4,
56
- end: 3,
57
- expected: [],
58
- }, // start > end
9
+ test.each([
10
+ {
11
+ start: 0,
12
+ end: 5,
13
+ expected: [0, 1, 2, 3, 4],
14
+ }, // normal
15
+ {
16
+ start: 0,
17
+ end: 5,
18
+ expected: [0, 1, 2, 3, 4],
19
+ }, // one side overflow
20
+ {
21
+ start: -1,
22
+ end: 5,
23
+ expected: [0, 1, 2, 3, 4],
24
+ }, // one side overflow
25
+ {
26
+ start: -1,
27
+ end: 6,
28
+ expected: [0, 1, 2, 3, 4],
29
+ }, // both sides overflow
30
+ {
31
+ start: 0,
32
+ end: 3,
33
+ expected: [0, 1, 2],
34
+ }, // normal
35
+ {
36
+ start: 1,
37
+ end: 3,
38
+ expected: [1, 2],
39
+ }, // normal
40
+ {
41
+ start: -1,
42
+ end: 3,
43
+ expected: [0, 1, 2],
44
+ }, // one side overflow
45
+ {
46
+ start: 3,
47
+ end: 5,
48
+ expected: [3, 4],
49
+ }, // normal
50
+ {
51
+ start: 4,
52
+ end: 3,
53
+ expected: [],
54
+ }, // start > end
55
+ {
56
+ start: 0,
57
+ end: -1,
58
+ expected: [],
59
+ }, // start > end
60
+ {
61
+ start: -1,
62
+ end: -2,
63
+ expected: [],
64
+ }, // start > end
65
+ {
66
+ start: 6,
67
+ end: 9,
68
+ expected: [],
69
+ },
70
+ {
71
+ start: 6,
72
+ end: 3,
73
+ expected: [],
74
+ },
75
+ ] as const)('sliceClamped($start, $end)', ({ start, end, expected }) => {
76
+ expect(Arr.sliceClamped(list, start, end)).toStrictEqual(expected);
77
+ });
78
+ }
79
+
80
+ test('should be type error for index overflow for fixed length array', () => {
59
81
  {
60
- start: 0,
61
- end: -1,
62
- expected: [],
63
- }, // start > end
82
+ const array = [1, 2, 3, 4, 5] as const;
83
+ // @ts-expect-error end index is out of bounds
84
+ const result = Arr.sliceClamped(array, 0, 6);
85
+ expect(result).toStrictEqual(array);
86
+ }
64
87
  {
65
- start: -1,
66
- end: -2,
67
- expected: [],
68
- }, // start > end
88
+ const array = [1, 2, 3, 4, 5] as const;
89
+ // @ts-expect-error end index is out of bounds
90
+ const result = Arr.sliceClamped(array, 0, -6);
91
+ expect(result).toStrictEqual([]);
92
+ }
69
93
  {
70
- start: 6,
71
- end: 9,
72
- expected: [],
73
- },
94
+ const array = [1, 2, 3, 4, 5] as const;
95
+ // @ts-expect-error start index is out of bounds
96
+ const result = Arr.sliceClamped(array, -6, 5);
97
+ expect(result).toStrictEqual(array);
98
+ }
74
99
  {
75
- start: 6,
76
- end: 3,
77
- expected: [],
78
- },
79
- ] as const)('sliceClamped($start, $end)', ({ start, end, expected }) => {
80
- expect(Arr.sliceClamped(list, start, end)).toStrictEqual(expected);
100
+ const array = [1, 2, 3, 4, 5] as const;
101
+ // @ts-expect-error start index is out of bounds
102
+ const result = Arr.sliceClamped(array, 6, 5);
103
+ expect(result).toStrictEqual([]);
104
+ }
81
105
  });
82
106
 
83
107
  test('should slice with clamped indices', () => {