ts-data-forge 6.3.0 → 6.4.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.
- package/README.md +4 -4
- package/dist/array/impl/array-utils-creation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-creation.mjs.map +1 -1
- package/dist/array/impl/array-utils-element-access.d.mts +2 -2
- package/dist/array/impl/array-utils-element-access.mjs +2 -2
- package/dist/array/impl/array-utils-modification.d.mts +2 -2
- package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
- package/dist/array/impl/array-utils-modification.mjs +1 -2
- package/dist/array/impl/array-utils-modification.mjs.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.mjs +1 -1
- package/dist/array/impl/array-utils-search.d.mts +3 -1
- package/dist/array/impl/array-utils-search.d.mts.map +1 -1
- package/dist/array/impl/array-utils-search.mjs.map +1 -1
- package/dist/array/impl/array-utils-set-op.d.mts.map +1 -1
- package/dist/array/impl/array-utils-set-op.mjs +1 -0
- package/dist/array/impl/array-utils-set-op.mjs.map +1 -1
- package/dist/array/impl/array-utils-size.d.mts +1 -1
- package/dist/array/impl/array-utils-size.mjs +1 -1
- package/dist/array/impl/array-utils-validation.d.mts +2 -2
- package/dist/array/impl/array-utils-validation.mjs +2 -2
- package/dist/collections/imap.d.mts +3 -3
- package/dist/collections/iset-mapped.d.mts +3 -3
- package/dist/collections/iset.d.mts +3 -3
- package/dist/collections/queue.mjs +21 -21
- package/dist/collections/queue.mjs.map +1 -1
- package/dist/collections/stack.mjs +12 -12
- package/dist/collections/stack.mjs.map +1 -1
- package/dist/functional/match.d.mts +1 -1
- package/dist/functional/match.d.mts.map +1 -1
- package/dist/globals.d.mts +1 -1
- package/dist/guard/has-key.d.mts +1 -1
- package/dist/guard/has-key.mjs +1 -1
- package/dist/guard/is-non-null-object.d.mts +1 -1
- package/dist/guard/is-non-null-object.mjs +1 -1
- package/dist/guard/is-record.d.mts +1 -1
- package/dist/guard/is-record.mjs +1 -1
- package/dist/guard/is-type.d.mts +23 -15
- package/dist/guard/is-type.d.mts.map +1 -1
- package/dist/guard/is-type.mjs +23 -15
- package/dist/guard/is-type.mjs.map +1 -1
- package/dist/number/num.d.mts +4 -4
- package/dist/number/num.d.mts.map +1 -1
- package/dist/number/num.mjs.map +1 -1
- package/dist/object/object.d.mts +1 -1
- package/dist/object/object.mjs +1 -1
- package/dist/others/memoize-function.d.mts +3 -2
- package/dist/others/memoize-function.d.mts.map +1 -1
- package/dist/others/memoize-function.mjs +10 -39
- package/dist/others/memoize-function.mjs.map +1 -1
- package/package.json +14 -11
- package/src/array/impl/array-utils-creation.mts +1 -3
- package/src/array/impl/array-utils-creation.test.mts +13 -5
- package/src/array/impl/array-utils-element-access.mts +2 -2
- package/src/array/impl/array-utils-iterators.test.mts +8 -3
- package/src/array/impl/array-utils-modification.mts +5 -6
- package/src/array/impl/array-utils-modification.test.mts +3 -3
- package/src/array/impl/array-utils-overload-type-error.test.mts +1 -1
- package/src/array/impl/array-utils-reducing-value.test.mts +5 -5
- package/src/array/impl/array-utils-search.mts +9 -7
- package/src/array/impl/array-utils-search.test.mts +2 -2
- package/src/array/impl/array-utils-set-op.mts +2 -1
- package/src/array/impl/array-utils-size.mts +1 -1
- package/src/array/impl/array-utils-transformation.test.mts +23 -22
- package/src/array/impl/array-utils-validation.mts +2 -2
- package/src/array/impl/array-utils-validation.test.mts +36 -29
- package/src/array/impl/array.test.mts +3 -0
- package/src/collections/imap-mapped.test.mts +5 -2
- package/src/collections/imap.mts +3 -3
- package/src/collections/iset-mapped.mts +3 -3
- package/src/collections/iset-mapped.test.mts +1 -1
- package/src/collections/iset.mts +3 -3
- package/src/collections/queue.mts +21 -21
- package/src/collections/queue.test.mts +1 -1
- package/src/collections/stack.mts +12 -12
- package/src/functional/match.mts +21 -12
- package/src/globals.d.mts +1 -1
- package/src/guard/has-key.mts +1 -1
- package/src/guard/has-key.test.mts +16 -35
- package/src/guard/is-error.test.mts +1 -1
- package/src/guard/is-non-empty-string.test.mts +1 -1
- package/src/guard/is-non-null-object.mts +1 -1
- package/src/guard/is-non-null-object.test.mts +1 -1
- package/src/guard/is-primitive.test.mts +1 -1
- package/src/guard/is-record.mts +1 -1
- package/src/guard/is-type.mts +23 -15
- package/src/guard/is-type.test.mts +6 -6
- package/src/json/json.test.mts +2 -0
- package/src/number/num.mts +2 -6
- package/src/object/object.mts +1 -1
- package/src/object/object.test.mts +7 -5
- package/src/others/cast-mutable.test.mts +7 -4
- package/src/others/map-nullable.test.mts +3 -3
- package/src/others/memoize-function.mts +35 -17
- package/src/others/memoize-function.test.mts +25 -0
|
@@ -20,6 +20,7 @@ describe(entries, () => {
|
|
|
20
20
|
|
|
21
21
|
const es = Array.from(entries(tuple));
|
|
22
22
|
|
|
23
|
+
// transformer-ignore-next-line
|
|
23
24
|
expectType<typeof es, (readonly [Uint32, 10 | 20 | 30])[]>('=');
|
|
24
25
|
|
|
25
26
|
assert.deepStrictEqual(es, [
|
|
@@ -30,7 +31,7 @@ describe(entries, () => {
|
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
test('should work with empty array', () => {
|
|
33
|
-
const empty: string[] = [];
|
|
34
|
+
const empty: readonly string[] = [];
|
|
34
35
|
|
|
35
36
|
const es = Array.from(entries(empty));
|
|
36
37
|
|
|
@@ -42,6 +43,7 @@ describe(entries, () => {
|
|
|
42
43
|
|
|
43
44
|
const es = Array.from(entries(mixed));
|
|
44
45
|
|
|
46
|
+
// transformer-ignore-next-line
|
|
45
47
|
expectType<typeof es, (readonly [Uint32, 1 | 'hello' | true])[]>('=');
|
|
46
48
|
|
|
47
49
|
assert.deepStrictEqual(es, [
|
|
@@ -68,13 +70,14 @@ describe(values, () => {
|
|
|
68
70
|
|
|
69
71
|
const vs = Array.from(values(tuple));
|
|
70
72
|
|
|
73
|
+
// transformer-ignore-next-line
|
|
71
74
|
expectType<typeof vs, ('a' | 'b' | 'c')[]>('=');
|
|
72
75
|
|
|
73
76
|
assert.deepStrictEqual(vs, ['a', 'b', 'c']);
|
|
74
77
|
});
|
|
75
78
|
|
|
76
79
|
test('should work with empty array', () => {
|
|
77
|
-
const empty: number[] = [];
|
|
80
|
+
const empty: readonly number[] = [];
|
|
78
81
|
|
|
79
82
|
const vs = Array.from(values(empty));
|
|
80
83
|
|
|
@@ -86,6 +89,7 @@ describe(values, () => {
|
|
|
86
89
|
|
|
87
90
|
const vs = Array.from(values(mixed));
|
|
88
91
|
|
|
92
|
+
// transformer-ignore-next-line
|
|
89
93
|
expectType<typeof vs, (1 | 'hello' | null)[]>('=');
|
|
90
94
|
|
|
91
95
|
assert.deepStrictEqual(vs, [1, 'hello', null]);
|
|
@@ -106,13 +110,14 @@ describe(indices, () => {
|
|
|
106
110
|
|
|
107
111
|
const ks = Array.from(indices(tuple));
|
|
108
112
|
|
|
113
|
+
// transformer-ignore-next-line
|
|
109
114
|
expectType<typeof ks, Uint32[]>('=');
|
|
110
115
|
|
|
111
116
|
assert.deepStrictEqual(ks, [asUint32(0), asUint32(1)]);
|
|
112
117
|
});
|
|
113
118
|
|
|
114
119
|
test('should work with empty array', () => {
|
|
115
|
-
const empty: string[] = [];
|
|
120
|
+
const empty: readonly string[] = [];
|
|
116
121
|
|
|
117
122
|
const ks = Array.from(indices(empty));
|
|
118
123
|
|
|
@@ -8,7 +8,7 @@ import { copy, create } from './array-utils-creation.mjs';
|
|
|
8
8
|
* @example
|
|
9
9
|
*
|
|
10
10
|
* ```ts
|
|
11
|
-
* const scores: number[] = [10, 20, 30];
|
|
11
|
+
* const scores: readonly number[] = [10, 20, 30];
|
|
12
12
|
*
|
|
13
13
|
* const updated = Arr.set(scores, 1, 25);
|
|
14
14
|
*
|
|
@@ -46,8 +46,7 @@ export function set<E, const V = E>(
|
|
|
46
46
|
case 3: {
|
|
47
47
|
const [array, index, newValue] = args;
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
return (array as (E | V)[]).with(index, newValue);
|
|
49
|
+
return (array as readonly (E | V)[]).with(index, newValue);
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
case 2: {
|
|
@@ -64,7 +63,7 @@ export function set<E, const V = E>(
|
|
|
64
63
|
* @example
|
|
65
64
|
*
|
|
66
65
|
* ```ts
|
|
67
|
-
* const temperatures: number[] = [20, 21, 22];
|
|
66
|
+
* const temperatures: readonly number[] = [20, 21, 22];
|
|
68
67
|
*
|
|
69
68
|
* const increased = Arr.toUpdated(temperatures, 1, (value) => value + 5);
|
|
70
69
|
*
|
|
@@ -116,8 +115,8 @@ export function toUpdated<E, V = E>(
|
|
|
116
115
|
case 3: {
|
|
117
116
|
const [array, index, updater] = args;
|
|
118
117
|
|
|
119
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
120
|
-
return (array as (E | V)[]).with(index, updater(array[index]!));
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
119
|
+
return (array as readonly (E | V)[]).with(index, updater(array[index]!));
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
case 2: {
|
|
@@ -104,7 +104,7 @@ describe('Arr modifications', () => {
|
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
test('case 4 (number[])', () => {
|
|
107
|
-
const xs: number[] = [1, 2, 3];
|
|
107
|
+
const xs: readonly number[] = [1, 2, 3];
|
|
108
108
|
|
|
109
109
|
const result = toRemoved(xs, 5);
|
|
110
110
|
|
|
@@ -134,7 +134,7 @@ describe('Arr modifications', () => {
|
|
|
134
134
|
});
|
|
135
135
|
|
|
136
136
|
test('case 2', () => {
|
|
137
|
-
const xs: number[] = [1, 2, 3];
|
|
137
|
+
const xs: readonly number[] = [1, 2, 3];
|
|
138
138
|
|
|
139
139
|
const result = toPushed(xs, 4 as const);
|
|
140
140
|
|
|
@@ -164,7 +164,7 @@ describe('Arr modifications', () => {
|
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
test('case 2', () => {
|
|
167
|
-
const xs: number[] = [1, 2, 3];
|
|
167
|
+
const xs: readonly number[] = [1, 2, 3];
|
|
168
168
|
|
|
169
169
|
const result = toUnshifted(xs, 4 as const);
|
|
170
170
|
|
|
@@ -145,7 +145,7 @@ describe('Array overloaded functions - type error validation', () => {
|
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
test('spread with incorrect types should cause errors', () => {
|
|
148
|
-
const invalidArgs: [string[], (x: string) => number] = [
|
|
148
|
+
const invalidArgs: readonly [readonly string[], (x: string) => number] = [
|
|
149
149
|
['a'],
|
|
150
150
|
(x) => x.length,
|
|
151
151
|
];
|
|
@@ -152,11 +152,11 @@ describe('Arr reducing value', () => {
|
|
|
152
152
|
});
|
|
153
153
|
|
|
154
154
|
test('case 2: empty array', () => {
|
|
155
|
-
const arr: readonly { x: number }[] = [];
|
|
155
|
+
const arr: readonly Readonly<{ x: number }>[] = [];
|
|
156
156
|
|
|
157
157
|
const res = minBy(arr, (a) => a.x);
|
|
158
158
|
|
|
159
|
-
expectType<typeof res, Optional<{ x: number }
|
|
159
|
+
expectType<typeof res, Optional<Readonly<{ x: number }>>>('=');
|
|
160
160
|
|
|
161
161
|
assert.isTrue(Optional.isNone(res));
|
|
162
162
|
});
|
|
@@ -228,11 +228,11 @@ describe('Arr reducing value', () => {
|
|
|
228
228
|
});
|
|
229
229
|
|
|
230
230
|
test('case 2: empty array', () => {
|
|
231
|
-
const arr: readonly { x: number }[] = [];
|
|
231
|
+
const arr: readonly Readonly<{ x: number }>[] = [];
|
|
232
232
|
|
|
233
233
|
const res = maxBy(arr, (a) => a.x);
|
|
234
234
|
|
|
235
|
-
expectType<typeof res, Optional<{ x: number }
|
|
235
|
+
expectType<typeof res, Optional<Readonly<{ x: number }>>>('=');
|
|
236
236
|
|
|
237
237
|
assert.isTrue(Optional.isNone(res));
|
|
238
238
|
});
|
|
@@ -332,7 +332,7 @@ describe('Arr reducing value', () => {
|
|
|
332
332
|
});
|
|
333
333
|
|
|
334
334
|
test('case 2: empty array', () => {
|
|
335
|
-
const arr: readonly { x: number }[] = [];
|
|
335
|
+
const arr: readonly Readonly<{ x: number }>[] = [];
|
|
336
336
|
|
|
337
337
|
const res = countBy(arr, (a) => a.x);
|
|
338
338
|
|
|
@@ -15,7 +15,9 @@ import { asUint32 } from '../../number/index.mjs';
|
|
|
15
15
|
*
|
|
16
16
|
* const found = Arr.find(users, (user) => user.id === 2);
|
|
17
17
|
*
|
|
18
|
-
* const missing = Arr.find<{ id: number }
|
|
18
|
+
* const missing = Arr.find<Readonly<{ id: number }>>((user) => user.id === 3)(
|
|
19
|
+
* users,
|
|
20
|
+
* );
|
|
19
21
|
*
|
|
20
22
|
* assert.deepStrictEqual(found, Optional.some({ id: 2, name: 'Grace' }));
|
|
21
23
|
*
|
|
@@ -225,7 +227,7 @@ export function findIndex<E>(
|
|
|
225
227
|
arr: readonly E[],
|
|
226
228
|
) => boolean,
|
|
227
229
|
]
|
|
228
|
-
): SizeType.Arr |
|
|
230
|
+
): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
|
|
229
231
|
switch (args.length) {
|
|
230
232
|
case 2: {
|
|
231
233
|
const [array, predicate] = args;
|
|
@@ -292,7 +294,7 @@ export function findLastIndex<E>(
|
|
|
292
294
|
arr: readonly E[],
|
|
293
295
|
) => boolean,
|
|
294
296
|
]
|
|
295
|
-
): SizeType.Arr |
|
|
297
|
+
): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
|
|
296
298
|
switch (args.length) {
|
|
297
299
|
case 2: {
|
|
298
300
|
const [array, predicate] = args;
|
|
@@ -350,7 +352,7 @@ export function indexOf<E>(
|
|
|
350
352
|
...args:
|
|
351
353
|
| readonly [array: readonly E[], searchElement: E]
|
|
352
354
|
| readonly [searchElement: E]
|
|
353
|
-
): SizeType.Arr |
|
|
355
|
+
): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
|
|
354
356
|
switch (args.length) {
|
|
355
357
|
case 2: {
|
|
356
358
|
const [array, searchElement] = args;
|
|
@@ -418,7 +420,7 @@ export function indexOfFrom<E>(
|
|
|
418
420
|
fromIndex: SizeType.ArgArrWithNegative,
|
|
419
421
|
]
|
|
420
422
|
| readonly [searchElement: E, fromIndex: SizeType.ArgArrWithNegative]
|
|
421
|
-
): SizeType.Arr |
|
|
423
|
+
): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
|
|
422
424
|
switch (args.length) {
|
|
423
425
|
case 3: {
|
|
424
426
|
const [array, searchElement, fromIndex] = args;
|
|
@@ -477,7 +479,7 @@ export function lastIndexOf<E>(
|
|
|
477
479
|
...args:
|
|
478
480
|
| readonly [array: readonly E[], searchElement: E]
|
|
479
481
|
| readonly [searchElement: E]
|
|
480
|
-
): SizeType.Arr |
|
|
482
|
+
): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
|
|
481
483
|
switch (args.length) {
|
|
482
484
|
case 2: {
|
|
483
485
|
const [array, searchElement] = args;
|
|
@@ -545,7 +547,7 @@ export function lastIndexOfFrom<E>(
|
|
|
545
547
|
fromIndex: SizeType.ArgArrWithNegative,
|
|
546
548
|
]
|
|
547
549
|
| readonly [searchElement: E, fromIndex: SizeType.ArgArrWithNegative]
|
|
548
|
-
): SizeType.Arr |
|
|
550
|
+
): SizeType.Arr | ((array: readonly E[]) => SizeType.Arr | -1) | -1 {
|
|
549
551
|
switch (args.length) {
|
|
550
552
|
case 3: {
|
|
551
553
|
const [array, searchElement, fromIndex] = args;
|
|
@@ -123,7 +123,7 @@ describe('Arr search operations', () => {
|
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
test('should work with empty array', () => {
|
|
126
|
-
const empty: number[] = [];
|
|
126
|
+
const empty: readonly number[] = [];
|
|
127
127
|
|
|
128
128
|
const result = findLast(empty, (n) => n > 0);
|
|
129
129
|
|
|
@@ -206,7 +206,7 @@ describe('Arr search operations', () => {
|
|
|
206
206
|
});
|
|
207
207
|
|
|
208
208
|
test('should work with empty array', () => {
|
|
209
|
-
const empty: number[] = [];
|
|
209
|
+
const empty: readonly number[] = [];
|
|
210
210
|
|
|
211
211
|
const result = findLastIndex(empty, (n) => n > 0);
|
|
212
212
|
|
|
@@ -103,8 +103,9 @@ export const setIntersection = <
|
|
|
103
103
|
array1: readonly E1[],
|
|
104
104
|
array2: readonly E2[],
|
|
105
105
|
): readonly (E1 & E2)[] =>
|
|
106
|
+
// transformer-ignore-next-line
|
|
106
107
|
// eslint-disable-next-line total-functions/no-unsafe-type-assertion
|
|
107
|
-
array1.filter((e) => array2.includes(e
|
|
108
|
+
(array1 as readonly (E1 & E2)[]).filter((e) => array2.includes(e));
|
|
108
109
|
|
|
109
110
|
/**
|
|
110
111
|
* Returns the set difference of two arrays (elements in first but not in second).
|
|
@@ -164,6 +164,7 @@ describe('Arr transformations', () => {
|
|
|
164
164
|
|
|
165
165
|
const _nativeResult = xs.toReversed();
|
|
166
166
|
|
|
167
|
+
// transformer-ignore-next-line
|
|
167
168
|
expectType<typeof _nativeResult, (1 | 2 | 3)[]>('=');
|
|
168
169
|
|
|
169
170
|
const result = toReversed([1, 2, 3]);
|
|
@@ -318,7 +319,7 @@ describe('Arr transformations', () => {
|
|
|
318
319
|
});
|
|
319
320
|
|
|
320
321
|
test('should work with empty array', () => {
|
|
321
|
-
const empty: readonly { value: number }[] = [];
|
|
322
|
+
const empty: readonly Readonly<{ value: number }>[] = [];
|
|
322
323
|
|
|
323
324
|
const result = toSortedBy(empty, (item) => item.value);
|
|
324
325
|
|
|
@@ -326,7 +327,7 @@ describe('Arr transformations', () => {
|
|
|
326
327
|
});
|
|
327
328
|
|
|
328
329
|
test('toSortedBy should work with empty array', () => {
|
|
329
|
-
const empty: readonly { value: number }[] = [];
|
|
330
|
+
const empty: readonly Readonly<{ value: number }>[] = [];
|
|
330
331
|
|
|
331
332
|
const result = toSortedBy(empty, (item) => item.value);
|
|
332
333
|
|
|
@@ -344,7 +345,7 @@ describe('Arr transformations', () => {
|
|
|
344
345
|
});
|
|
345
346
|
|
|
346
347
|
test('should work with type guards', () => {
|
|
347
|
-
const mixed: (string | number | null)[] = [
|
|
348
|
+
const mixed: readonly (string | number | null)[] = [
|
|
348
349
|
'hello',
|
|
349
350
|
42,
|
|
350
351
|
null,
|
|
@@ -392,7 +393,7 @@ describe('Arr transformations', () => {
|
|
|
392
393
|
});
|
|
393
394
|
|
|
394
395
|
test('should work with empty array', () => {
|
|
395
|
-
const empty: number[] = [];
|
|
396
|
+
const empty: readonly number[] = [];
|
|
396
397
|
|
|
397
398
|
const result = filter(empty, (n) => n > 0);
|
|
398
399
|
|
|
@@ -489,7 +490,7 @@ describe('Arr transformations', () => {
|
|
|
489
490
|
});
|
|
490
491
|
|
|
491
492
|
test('should work with empty array', () => {
|
|
492
|
-
const empty: readonly { id: number }[] = [];
|
|
493
|
+
const empty: readonly Readonly<{ id: number }>[] = [];
|
|
493
494
|
|
|
494
495
|
const result = uniqBy(empty, (item) => item.id);
|
|
495
496
|
|
|
@@ -609,7 +610,7 @@ describe('Arr transformations', () => {
|
|
|
609
610
|
});
|
|
610
611
|
|
|
611
612
|
test('should work with empty arrays', () => {
|
|
612
|
-
const empty: string[] = [];
|
|
613
|
+
const empty: readonly string[] = [];
|
|
613
614
|
|
|
614
615
|
const result = flatMap(empty, (s) => s.split(''));
|
|
615
616
|
|
|
@@ -833,14 +834,14 @@ describe('Arr transformations', () => {
|
|
|
833
834
|
typeof result,
|
|
834
835
|
IMap<
|
|
835
836
|
1 | 2 | 3,
|
|
836
|
-
readonly
|
|
837
|
-
|
|
|
838
|
-
|
|
|
839
|
-
|
|
|
840
|
-
|
|
|
841
|
-
|
|
|
842
|
-
|
|
|
843
|
-
|
|
837
|
+
readonly Readonly<
|
|
838
|
+
| { x: 1; y: 1 }
|
|
839
|
+
| { x: 1; y: 2 }
|
|
840
|
+
| { x: 1; y: 3 }
|
|
841
|
+
| { x: 2; y: 1 }
|
|
842
|
+
| { x: 2; y: 2 }
|
|
843
|
+
| { x: 3; y: 1 }
|
|
844
|
+
>[]
|
|
844
845
|
>
|
|
845
846
|
>('=');
|
|
846
847
|
|
|
@@ -849,14 +850,14 @@ describe('Arr transformations', () => {
|
|
|
849
850
|
result,
|
|
850
851
|
IMap.create<
|
|
851
852
|
1 | 2 | 3,
|
|
852
|
-
readonly
|
|
853
|
-
|
|
|
854
|
-
|
|
|
855
|
-
|
|
|
856
|
-
|
|
|
857
|
-
|
|
|
858
|
-
|
|
|
859
|
-
|
|
853
|
+
readonly Readonly<
|
|
854
|
+
| { x: 1; y: 1 }
|
|
855
|
+
| { x: 1; y: 2 }
|
|
856
|
+
| { x: 1; y: 3 }
|
|
857
|
+
| { x: 2; y: 1 }
|
|
858
|
+
| { x: 2; y: 2 }
|
|
859
|
+
| { x: 3; y: 1 }
|
|
860
|
+
>[]
|
|
860
861
|
>([
|
|
861
862
|
[
|
|
862
863
|
1,
|
|
@@ -63,9 +63,9 @@ export const isEmpty = <E,>(array: readonly E[]): array is readonly [] =>
|
|
|
63
63
|
* @example
|
|
64
64
|
*
|
|
65
65
|
* ```ts
|
|
66
|
-
* const users: readonly { id: number }[] = [{ id: 1 }];
|
|
66
|
+
* const users: readonly Readonly<{ id: number }>[] = [{ id: 1 }];
|
|
67
67
|
*
|
|
68
|
-
* const emptyUsers: readonly { id: number }[] = [];
|
|
68
|
+
* const emptyUsers: readonly Readonly<{ id: number }>[] = [];
|
|
69
69
|
*
|
|
70
70
|
* assert.isTrue(Arr.isNonEmpty(users));
|
|
71
71
|
*
|
|
@@ -36,7 +36,7 @@ describe('Arr validations', () => {
|
|
|
36
36
|
|
|
37
37
|
test('should refine union types correctly', () => {
|
|
38
38
|
const processValue = (
|
|
39
|
-
value: string | readonly number[]
|
|
39
|
+
value: string | null | readonly number[],
|
|
40
40
|
): number => {
|
|
41
41
|
if (isArray(value)) {
|
|
42
42
|
// value should be typed as number[]
|
|
@@ -66,10 +66,10 @@ describe('Arr validations', () => {
|
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
test('should work with mutable arrays', () => {
|
|
69
|
-
const mutableArray: number[] = [1, 2, 3];
|
|
69
|
+
const mutableArray: readonly number[] = [1, 2, 3];
|
|
70
70
|
|
|
71
71
|
if (isArray(mutableArray)) {
|
|
72
|
-
expectType<typeof mutableArray, number[]>('=');
|
|
72
|
+
expectType<typeof mutableArray, readonly number[]>('=');
|
|
73
73
|
|
|
74
74
|
expect(mutableArray).toHaveLength(3);
|
|
75
75
|
}
|
|
@@ -108,10 +108,10 @@ describe('Arr validations', () => {
|
|
|
108
108
|
value:
|
|
109
109
|
| string
|
|
110
110
|
| boolean
|
|
111
|
-
| readonly number[]
|
|
112
|
-
| Readonly<{ a: number }>
|
|
113
111
|
| unknown
|
|
114
|
-
| object
|
|
112
|
+
| object
|
|
113
|
+
| readonly number[]
|
|
114
|
+
| Readonly<{ a: number }>,
|
|
115
115
|
): number => {
|
|
116
116
|
if (isArray(value)) {
|
|
117
117
|
// Only number[] should remain
|
|
@@ -123,7 +123,7 @@ describe('Arr validations', () => {
|
|
|
123
123
|
// Non-array types
|
|
124
124
|
expectType<
|
|
125
125
|
typeof value,
|
|
126
|
-
string | boolean | Readonly<{ a: number }>
|
|
126
|
+
string | boolean | unknown | object | Readonly<{ a: number }>
|
|
127
127
|
>('=');
|
|
128
128
|
|
|
129
129
|
return -1;
|
|
@@ -273,7 +273,7 @@ describe('Arr validations', () => {
|
|
|
273
273
|
});
|
|
274
274
|
|
|
275
275
|
test('should handle intersection types', () => {
|
|
276
|
-
type TaggedArray = readonly number[] & { tag: string }
|
|
276
|
+
type TaggedArray = readonly number[] & Readonly<{ tag: string }>;
|
|
277
277
|
|
|
278
278
|
const tagged = Object.assign([1, 2, 3], { tag: 'test' }) as TaggedArray;
|
|
279
279
|
|
|
@@ -297,8 +297,10 @@ describe('Arr validations', () => {
|
|
|
297
297
|
|
|
298
298
|
test('should handle complex union discrimination', () => {
|
|
299
299
|
type ComplexUnion =
|
|
300
|
-
|
|
|
301
|
-
|
|
300
|
+
| Readonly<
|
|
301
|
+
| { type: 'array'; data: readonly string[] }
|
|
302
|
+
| { type: 'object'; data: Record<string, unknown> }
|
|
303
|
+
>
|
|
302
304
|
| readonly number[]
|
|
303
305
|
| string
|
|
304
306
|
| null;
|
|
@@ -325,8 +327,10 @@ describe('Arr validations', () => {
|
|
|
325
327
|
|
|
326
328
|
expectType<
|
|
327
329
|
typeof value,
|
|
328
|
-
|
|
329
|
-
|
|
330
|
+
Readonly<
|
|
331
|
+
| { type: 'array'; data: readonly string[] }
|
|
332
|
+
| { type: 'object'; data: Record<string, unknown> }
|
|
333
|
+
>
|
|
330
334
|
>('=');
|
|
331
335
|
|
|
332
336
|
return -1;
|
|
@@ -435,15 +439,16 @@ describe('Arr validations', () => {
|
|
|
435
439
|
});
|
|
436
440
|
|
|
437
441
|
test('should work with unknown array type', () => {
|
|
438
|
-
const
|
|
442
|
+
const mut_arr: number[] = [1, 2];
|
|
439
443
|
|
|
440
|
-
assert.isTrue(isArrayOfLength(
|
|
444
|
+
assert.isTrue(isArrayOfLength(mut_arr, 2));
|
|
441
445
|
|
|
442
|
-
if (isArrayOfLength(
|
|
443
|
-
|
|
446
|
+
if (isArrayOfLength(mut_arr, 2)) {
|
|
447
|
+
// transformer-ignore-next-line
|
|
448
|
+
expectType<typeof mut_arr, number[] & ArrayOfLength<2, number>>('=');
|
|
444
449
|
}
|
|
445
450
|
|
|
446
|
-
assert.isFalse(isArrayOfLength(
|
|
451
|
+
assert.isFalse(isArrayOfLength(mut_arr, 3));
|
|
447
452
|
});
|
|
448
453
|
|
|
449
454
|
test('should work with unknown readonly array type', () => {
|
|
@@ -525,23 +530,25 @@ describe('Arr validations', () => {
|
|
|
525
530
|
});
|
|
526
531
|
|
|
527
532
|
test('should work with unknown array type', () => {
|
|
528
|
-
const
|
|
533
|
+
const mut_arr: number[] = [1, 2];
|
|
529
534
|
|
|
530
|
-
assert.isTrue(isArrayAtLeastLength(
|
|
535
|
+
assert.isTrue(isArrayAtLeastLength(mut_arr, 2));
|
|
531
536
|
|
|
532
|
-
|
|
537
|
+
// transformer-ignore-next-line
|
|
538
|
+
expectType<typeof mut_arr, number[] & ArrayAtLeastLen<2, number>>('=');
|
|
533
539
|
|
|
534
|
-
assert.isFalse(isArrayAtLeastLength(
|
|
540
|
+
assert.isFalse(isArrayAtLeastLength(mut_arr, 3));
|
|
535
541
|
});
|
|
536
542
|
|
|
537
543
|
test('should work with unknown array type 2', () => {
|
|
538
|
-
const
|
|
544
|
+
const mut_arr: number[] = [1, 2];
|
|
539
545
|
|
|
540
|
-
assert.isTrue(isArrayAtLeastLength(
|
|
546
|
+
assert.isTrue(isArrayAtLeastLength(mut_arr, 1));
|
|
541
547
|
|
|
542
|
-
|
|
548
|
+
// transformer-ignore-next-line
|
|
549
|
+
expectType<typeof mut_arr, number[] & ArrayAtLeastLen<1, number>>('=');
|
|
543
550
|
|
|
544
|
-
assert.isFalse(isArrayAtLeastLength(
|
|
551
|
+
assert.isFalse(isArrayAtLeastLength(mut_arr, 3));
|
|
545
552
|
});
|
|
546
553
|
|
|
547
554
|
test('should return true for arrays of at least specified length (additional)', () => {
|
|
@@ -589,7 +596,7 @@ describe('Arr validations', () => {
|
|
|
589
596
|
});
|
|
590
597
|
|
|
591
598
|
test('should work as type guard', () => {
|
|
592
|
-
const mixed: (string | number)[] = ['hello', 'world'];
|
|
599
|
+
const mixed: readonly (string | number)[] = ['hello', 'world'];
|
|
593
600
|
|
|
594
601
|
if (every(mixed, (x): x is string => typeof x === 'string')) {
|
|
595
602
|
// TypeScript narrows mixed to readonly string[] here
|
|
@@ -612,7 +619,7 @@ describe('Arr validations', () => {
|
|
|
612
619
|
|
|
613
620
|
const allStrings = every(isString);
|
|
614
621
|
|
|
615
|
-
const data: unknown[] = ['a', 'b', 'c'];
|
|
622
|
+
const data: readonly unknown[] = ['a', 'b', 'c'];
|
|
616
623
|
|
|
617
624
|
if (allStrings(data)) {
|
|
618
625
|
// TypeScript narrows data to readonly string[] here
|
|
@@ -621,7 +628,7 @@ describe('Arr validations', () => {
|
|
|
621
628
|
});
|
|
622
629
|
|
|
623
630
|
test('should return true for empty array', () => {
|
|
624
|
-
const empty: number[] = [];
|
|
631
|
+
const empty: readonly number[] = [];
|
|
625
632
|
|
|
626
633
|
const result = every(empty, (n) => n > 0);
|
|
627
634
|
|
|
@@ -665,7 +672,7 @@ describe('Arr validations', () => {
|
|
|
665
672
|
});
|
|
666
673
|
|
|
667
674
|
test('should return false for empty array', () => {
|
|
668
|
-
const empty: number[] = [];
|
|
675
|
+
const empty: readonly number[] = [];
|
|
669
676
|
|
|
670
677
|
const result = some(empty, (n) => n > 0);
|
|
671
678
|
|
|
@@ -37,6 +37,7 @@ describe('Array.flat', () => {
|
|
|
37
37
|
|
|
38
38
|
expectType<
|
|
39
39
|
typeof result,
|
|
40
|
+
// transformer-ignore-next-line
|
|
40
41
|
(readonly [5, 6, readonly [7, 8]] | 1 | 2 | 3 | 4)[]
|
|
41
42
|
>('=');
|
|
42
43
|
|
|
@@ -137,6 +138,7 @@ describe('Array.filter', () => {
|
|
|
137
138
|
|
|
138
139
|
const filtered = xs.filter((x): x is 1 | 3 => x % 2 === 1);
|
|
139
140
|
|
|
141
|
+
// transformer-ignore-next-line
|
|
140
142
|
expectType<typeof filtered, (1 | 3)[]>('=');
|
|
141
143
|
|
|
142
144
|
test('case 1', () => {
|
|
@@ -149,6 +151,7 @@ describe('Array.filter', () => {
|
|
|
149
151
|
|
|
150
152
|
const filtered = xs.filter((x) => x % 2 === 1);
|
|
151
153
|
|
|
154
|
+
// transformer-ignore-next-line
|
|
152
155
|
expectType<typeof filtered, (1 | 2 | 3)[]>('=');
|
|
153
156
|
|
|
154
157
|
test('case 2', () => {
|
|
@@ -5,7 +5,7 @@ const toKey = (a: Readonly<{ v: number }>): number => a.v;
|
|
|
5
5
|
|
|
6
6
|
const fromKey = (k: number): Readonly<{ v: number }> => ({ v: k });
|
|
7
7
|
|
|
8
|
-
type TestKey = { id: number; type: string }
|
|
8
|
+
type TestKey = Readonly<{ id: number; type: string }>;
|
|
9
9
|
|
|
10
10
|
const testKeyToString = (key: Readonly<TestKey>): string =>
|
|
11
11
|
`${key.type}_${key.id}`;
|
|
@@ -95,7 +95,10 @@ describe('IMapMapped.create', () => {
|
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
test('should handle complex key transformations', () => {
|
|
98
|
-
type ComplexKey = {
|
|
98
|
+
type ComplexKey = Readonly<{
|
|
99
|
+
nested: Readonly<{ id: number }>;
|
|
100
|
+
arr: readonly number[];
|
|
101
|
+
}>;
|
|
99
102
|
|
|
100
103
|
const complexKeyToString = (
|
|
101
104
|
key: DeepReadonly<{
|
package/src/collections/imap.mts
CHANGED
|
@@ -389,13 +389,13 @@ type IMapInterface<K extends MapSetKeyType, V> = Readonly<{
|
|
|
389
389
|
* ['b', 2],
|
|
390
390
|
* ]);
|
|
391
391
|
*
|
|
392
|
-
* const
|
|
392
|
+
* const mut_entries: (readonly [string, number])[] = [];
|
|
393
393
|
*
|
|
394
394
|
* for (const [key, value] of map.entries()) {
|
|
395
|
-
*
|
|
395
|
+
* mut_entries.push([key, value]);
|
|
396
396
|
* }
|
|
397
397
|
*
|
|
398
|
-
* assert.deepStrictEqual(
|
|
398
|
+
* assert.deepStrictEqual(mut_entries, [
|
|
399
399
|
* ['a', 1],
|
|
400
400
|
* ['b', 2],
|
|
401
401
|
* ]);
|
|
@@ -472,13 +472,13 @@ type ISetMappedInterface<K, KM extends MapSetKeyType> = Readonly<{
|
|
|
472
472
|
* fromKey,
|
|
473
473
|
* );
|
|
474
474
|
*
|
|
475
|
-
* const
|
|
475
|
+
* const mut_collected: Point[] = [];
|
|
476
476
|
*
|
|
477
477
|
* for (const point of set) {
|
|
478
|
-
*
|
|
478
|
+
* mut_collected.push(point);
|
|
479
479
|
* }
|
|
480
480
|
*
|
|
481
|
-
* assert.deepStrictEqual(
|
|
481
|
+
* assert.deepStrictEqual(mut_collected, [
|
|
482
482
|
* { x: 1, tag: 'a' },
|
|
483
483
|
* { x: 2, tag: 'b' },
|
|
484
484
|
* ]);
|
|
@@ -5,7 +5,7 @@ const toKey = (a: Readonly<{ v: number }>): number => a.v;
|
|
|
5
5
|
const fromKey = (k: number): Readonly<{ v: number }> => ({ v: k });
|
|
6
6
|
|
|
7
7
|
// Test types for additional functionality
|
|
8
|
-
type TestElement = { id: number; type: string }
|
|
8
|
+
type TestElement = Readonly<{ id: number; type: string }>;
|
|
9
9
|
|
|
10
10
|
const testElementToString = (el: Readonly<TestElement>): string =>
|
|
11
11
|
`${el.type}_${el.id}`;
|