ts-data-forge 6.3.0 → 6.3.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.
- 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/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
|
@@ -205,19 +205,19 @@ export type Queue<T> = Readonly<{
|
|
|
205
205
|
*/
|
|
206
206
|
class QueueClass<T> implements Queue<T> {
|
|
207
207
|
/** @internal Circular buffer to store queue elements. */
|
|
208
|
-
#
|
|
208
|
+
#mut_buffer: (T | undefined)[];
|
|
209
209
|
|
|
210
210
|
/** @internal Index of the first element (front of queue). */
|
|
211
|
-
#
|
|
211
|
+
#mut_head: number;
|
|
212
212
|
|
|
213
213
|
/** @internal Index where the next element will be added (back of queue). */
|
|
214
|
-
#
|
|
214
|
+
#mut_tail: number;
|
|
215
215
|
|
|
216
216
|
/** @internal Current number of elements in the queue. */
|
|
217
217
|
#mut_size: number;
|
|
218
218
|
|
|
219
219
|
/** @internal Current capacity of the buffer. */
|
|
220
|
-
#
|
|
220
|
+
#mut_capacity: number;
|
|
221
221
|
|
|
222
222
|
/** @internal Initial capacity for new queues. */
|
|
223
223
|
static readonly #INITIAL_CAPACITY = 8;
|
|
@@ -232,18 +232,18 @@ class QueueClass<T> implements Queue<T> {
|
|
|
232
232
|
Math.max(QueueClass.#INITIAL_CAPACITY, initialValues.length * 2),
|
|
233
233
|
);
|
|
234
234
|
|
|
235
|
-
this.#
|
|
235
|
+
this.#mut_buffer = Array.from<unknown, T | undefined>(
|
|
236
236
|
{ length: initialCapacity },
|
|
237
237
|
() => undefined,
|
|
238
238
|
);
|
|
239
239
|
|
|
240
|
-
this.#
|
|
240
|
+
this.#mut_head = 0;
|
|
241
241
|
|
|
242
|
-
this.#
|
|
242
|
+
this.#mut_tail = 0;
|
|
243
243
|
|
|
244
244
|
this.#mut_size = 0;
|
|
245
245
|
|
|
246
|
-
this.#
|
|
246
|
+
this.#mut_capacity = initialCapacity;
|
|
247
247
|
|
|
248
248
|
// Add initial values
|
|
249
249
|
for (const value of initialValues) {
|
|
@@ -281,11 +281,11 @@ class QueueClass<T> implements Queue<T> {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
284
|
-
const element = this.#
|
|
284
|
+
const element = this.#mut_buffer[this.#mut_head]!;
|
|
285
285
|
|
|
286
|
-
this.#
|
|
286
|
+
this.#mut_buffer[this.#mut_head] = undefined; // Clear reference for garbage collection
|
|
287
287
|
|
|
288
|
-
this.#
|
|
288
|
+
this.#mut_head = (this.#mut_head + 1) % this.#mut_capacity;
|
|
289
289
|
|
|
290
290
|
this.#mut_size -= 1;
|
|
291
291
|
|
|
@@ -311,13 +311,13 @@ class QueueClass<T> implements Queue<T> {
|
|
|
311
311
|
*/
|
|
312
312
|
enqueue(value: T): void {
|
|
313
313
|
// Resize if buffer is full
|
|
314
|
-
if (this.#mut_size === this.#
|
|
314
|
+
if (this.#mut_size === this.#mut_capacity) {
|
|
315
315
|
this.#resize();
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
this.#
|
|
318
|
+
this.#mut_buffer[this.#mut_tail] = value;
|
|
319
319
|
|
|
320
|
-
this.#
|
|
320
|
+
this.#mut_tail = (this.#mut_tail + 1) % this.#mut_capacity;
|
|
321
321
|
|
|
322
322
|
this.#mut_size += 1;
|
|
323
323
|
}
|
|
@@ -328,7 +328,7 @@ class QueueClass<T> implements Queue<T> {
|
|
|
328
328
|
* Doubles the capacity and reorganizes elements to maintain queue order.
|
|
329
329
|
*/
|
|
330
330
|
#resize(): void {
|
|
331
|
-
const newCapacity = asUint32(this.#
|
|
331
|
+
const newCapacity = asUint32(this.#mut_capacity * 2);
|
|
332
332
|
|
|
333
333
|
const newBuffer = Array.from<unknown, T | undefined>(
|
|
334
334
|
{ length: newCapacity },
|
|
@@ -337,18 +337,18 @@ class QueueClass<T> implements Queue<T> {
|
|
|
337
337
|
|
|
338
338
|
// Copy elements in order from head to tail
|
|
339
339
|
for (const i of range(asSafeUint(this.#mut_size))) {
|
|
340
|
-
const sourceIndex = (this.#
|
|
340
|
+
const sourceIndex = (this.#mut_head + i) % this.#mut_capacity;
|
|
341
341
|
|
|
342
|
-
newBuffer[i] = this.#
|
|
342
|
+
newBuffer[i] = this.#mut_buffer[sourceIndex];
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
-
this.#
|
|
345
|
+
this.#mut_buffer = newBuffer;
|
|
346
346
|
|
|
347
|
-
this.#
|
|
347
|
+
this.#mut_head = 0;
|
|
348
348
|
|
|
349
|
-
this.#
|
|
349
|
+
this.#mut_tail = this.#mut_size;
|
|
350
350
|
|
|
351
|
-
this.#
|
|
351
|
+
this.#mut_capacity = newCapacity;
|
|
352
352
|
}
|
|
353
353
|
}
|
|
354
354
|
|
|
@@ -481,7 +481,7 @@ describe('Queue test', () => {
|
|
|
481
481
|
});
|
|
482
482
|
|
|
483
483
|
test('should properly clean up references for garbage collection', () => {
|
|
484
|
-
const q = createQueue<{ id: number }
|
|
484
|
+
const q = createQueue<Readonly<{ id: number }>>();
|
|
485
485
|
|
|
486
486
|
const objects = Arr.seq(10).map((i) => ({ id: i }));
|
|
487
487
|
|
|
@@ -200,13 +200,13 @@ export type Stack<T> = Readonly<{
|
|
|
200
200
|
*/
|
|
201
201
|
class StackClass<T> implements Stack<T> {
|
|
202
202
|
/** @internal Dynamic array to store stack elements. */
|
|
203
|
-
#
|
|
203
|
+
#mut_buffer: (T | undefined)[];
|
|
204
204
|
|
|
205
205
|
/** @internal Current number of elements in the stack. */
|
|
206
206
|
#mut_size: Uint32;
|
|
207
207
|
|
|
208
208
|
/** @internal Current capacity of the buffer. */
|
|
209
|
-
#
|
|
209
|
+
#mut_capacity: Uint32;
|
|
210
210
|
|
|
211
211
|
/** @internal Initial capacity for new stacks. */
|
|
212
212
|
static readonly #INITIAL_CAPACITY = 8;
|
|
@@ -221,14 +221,14 @@ class StackClass<T> implements Stack<T> {
|
|
|
221
221
|
Math.max(StackClass.#INITIAL_CAPACITY, initialValues.length * 2),
|
|
222
222
|
);
|
|
223
223
|
|
|
224
|
-
this.#
|
|
224
|
+
this.#mut_buffer = Array.from<unknown, T | undefined>(
|
|
225
225
|
{ length: initialCapacity },
|
|
226
226
|
() => undefined,
|
|
227
227
|
);
|
|
228
228
|
|
|
229
229
|
this.#mut_size = asUint32(0);
|
|
230
230
|
|
|
231
|
-
this.#
|
|
231
|
+
this.#mut_capacity = initialCapacity;
|
|
232
232
|
|
|
233
233
|
// Add initial values
|
|
234
234
|
for (const value of initialValues) {
|
|
@@ -268,9 +268,9 @@ class StackClass<T> implements Stack<T> {
|
|
|
268
268
|
this.#mut_size = Uint32.sub(this.#mut_size, 1);
|
|
269
269
|
|
|
270
270
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
271
|
-
const element = this.#
|
|
271
|
+
const element = this.#mut_buffer[this.#mut_size]!;
|
|
272
272
|
|
|
273
|
-
this.#
|
|
273
|
+
this.#mut_buffer[this.#mut_size] = undefined; // Clear reference for garbage collection
|
|
274
274
|
|
|
275
275
|
return Optional.some(element);
|
|
276
276
|
}
|
|
@@ -294,11 +294,11 @@ class StackClass<T> implements Stack<T> {
|
|
|
294
294
|
*/
|
|
295
295
|
push(value: T): void {
|
|
296
296
|
// Resize if buffer is full
|
|
297
|
-
if (this.#mut_size === this.#
|
|
297
|
+
if (this.#mut_size === this.#mut_capacity) {
|
|
298
298
|
this.#resize();
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
this.#
|
|
301
|
+
this.#mut_buffer[this.#mut_size] = value;
|
|
302
302
|
|
|
303
303
|
this.#mut_size = Uint32.add(this.#mut_size, 1);
|
|
304
304
|
}
|
|
@@ -309,7 +309,7 @@ class StackClass<T> implements Stack<T> {
|
|
|
309
309
|
* Doubles the capacity while preserving all elements.
|
|
310
310
|
*/
|
|
311
311
|
#resize(): void {
|
|
312
|
-
const newCapacity = asUint32(this.#
|
|
312
|
+
const newCapacity = asUint32(this.#mut_capacity * 2);
|
|
313
313
|
|
|
314
314
|
const newBuffer = Array.from<unknown, T | undefined>(
|
|
315
315
|
{ length: newCapacity },
|
|
@@ -318,12 +318,12 @@ class StackClass<T> implements Stack<T> {
|
|
|
318
318
|
|
|
319
319
|
// Copy existing elements
|
|
320
320
|
for (const i of range(this.#mut_size)) {
|
|
321
|
-
newBuffer[i] = this.#
|
|
321
|
+
newBuffer[i] = this.#mut_buffer[i];
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
this.#
|
|
324
|
+
this.#mut_buffer = newBuffer;
|
|
325
325
|
|
|
326
|
-
this.#
|
|
326
|
+
this.#mut_capacity = newCapacity;
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
|
package/src/functional/match.mts
CHANGED
|
@@ -27,7 +27,7 @@ import { keyIsIn } from '../guard/index.mjs';
|
|
|
27
27
|
*
|
|
28
28
|
* const message = match<
|
|
29
29
|
* Status,
|
|
30
|
-
* { draft: string; review: string; published: string }
|
|
30
|
+
* Readonly<{ draft: string; review: string; published: string }>
|
|
31
31
|
* >(status, {
|
|
32
32
|
* draft: 'Work in progress',
|
|
33
33
|
* review: 'Awaiting feedback',
|
|
@@ -104,11 +104,15 @@ type StrictPropertyCheck<T, ExpectedKeys extends PropertyKey> =
|
|
|
104
104
|
type AllCasesCovered<Case extends PropertyKey, R> =
|
|
105
105
|
TypeEq<Case, keyof R> extends true ? true : false;
|
|
106
106
|
|
|
107
|
-
expectType<AllCasesCovered<'a' | 'b', { a: 1; b: 2 }
|
|
107
|
+
expectType<AllCasesCovered<'a' | 'b', Readonly<{ a: 1; b: 2 }>>, true>('=');
|
|
108
108
|
|
|
109
|
-
expectType<AllCasesCovered<'a' | 'b' | 'c', { a: 1; b: 2 }
|
|
109
|
+
expectType<AllCasesCovered<'a' | 'b' | 'c', Readonly<{ a: 1; b: 2 }>>, false>(
|
|
110
|
+
'=',
|
|
111
|
+
);
|
|
110
112
|
|
|
111
|
-
expectType<AllCasesCovered<'a' | 'b', { a: 1; b: 2; c: 3 }
|
|
113
|
+
expectType<AllCasesCovered<'a' | 'b', Readonly<{ a: 1; b: 2; c: 3 }>>, false>(
|
|
114
|
+
'=',
|
|
115
|
+
);
|
|
112
116
|
|
|
113
117
|
expectType<AllCasesCovered<string, Record<string, string>>, true>('=');
|
|
114
118
|
|
|
@@ -126,15 +130,20 @@ type IsLiteralUnionFullyCovered<
|
|
|
126
130
|
? AllCasesCovered<Case, R>
|
|
127
131
|
: false;
|
|
128
132
|
|
|
129
|
-
expectType<
|
|
133
|
+
expectType<
|
|
134
|
+
IsLiteralUnionFullyCovered<'a' | 'b', Readonly<{ a: 1; b: 2 }>>,
|
|
135
|
+
true
|
|
136
|
+
>('=');
|
|
130
137
|
|
|
131
|
-
expectType<
|
|
132
|
-
'
|
|
133
|
-
|
|
138
|
+
expectType<
|
|
139
|
+
IsLiteralUnionFullyCovered<'a' | 'b' | 'c', Readonly<{ a: 1; b: 2 }>>,
|
|
140
|
+
false
|
|
141
|
+
>('=');
|
|
134
142
|
|
|
135
|
-
expectType<
|
|
136
|
-
'
|
|
137
|
-
|
|
143
|
+
expectType<
|
|
144
|
+
IsLiteralUnionFullyCovered<'a' | 'b', Readonly<{ a: 1; b: 2; c: 3 }>>,
|
|
145
|
+
false
|
|
146
|
+
>('=');
|
|
138
147
|
|
|
139
148
|
expectType<IsLiteralUnionFullyCovered<string, Record<string, string>>, false>(
|
|
140
149
|
'=',
|
|
@@ -142,7 +151,7 @@ expectType<IsLiteralUnionFullyCovered<string, Record<string, string>>, false>(
|
|
|
142
151
|
|
|
143
152
|
expectType<
|
|
144
153
|
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
145
|
-
IsLiteralUnionFullyCovered<'a' | 'b' | string, { a: 1; b: 2 }
|
|
154
|
+
IsLiteralUnionFullyCovered<'a' | 'b' | string, Readonly<{ a: 1; b: 2 }>>,
|
|
146
155
|
false
|
|
147
156
|
>('=');
|
|
148
157
|
|
package/src/globals.d.mts
CHANGED
|
@@ -13,7 +13,7 @@ type ArgArrayIndex<Ar extends readonly unknown[]> =
|
|
|
13
13
|
|
|
14
14
|
type ArgArrayIndexWithNegative<Ar extends readonly unknown[]> =
|
|
15
15
|
IsFixedLengthList<Ar> extends true
|
|
16
|
-
? IndexOfTuple<[...Ar, 0]> | NegativeIndexOfTuple<Ar>
|
|
16
|
+
? IndexOfTuple<readonly [...Ar, 0]> | NegativeIndexOfTuple<Ar>
|
|
17
17
|
: SizeType.ArgArrWithNegative;
|
|
18
18
|
|
|
19
19
|
// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/length
|
package/src/guard/has-key.mts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* @example
|
|
18
18
|
*
|
|
19
19
|
* ```ts
|
|
20
|
-
* const maybeUser: { id?: number; name?: string } = { id: 42 };
|
|
20
|
+
* const maybeUser: Readonly<{ id?: number; name?: string }> = { id: 42 };
|
|
21
21
|
*
|
|
22
22
|
* if (hasKey(maybeUser, 'id')) {
|
|
23
23
|
* // `maybeUser` is now known to have an `id` property.
|
|
@@ -4,52 +4,42 @@ import { hasKey, type HasKeyReturnType } from './has-key.mjs';
|
|
|
4
4
|
test('hasKey type inferences', () => {
|
|
5
5
|
{
|
|
6
6
|
expectType<
|
|
7
|
-
HasKeyReturnType<Readonly<{ a: 0 }
|
|
7
|
+
HasKeyReturnType<Readonly<{ a: 0 } | { b: 1 }>, 'a'>,
|
|
8
8
|
Readonly<{ a: 0 }>
|
|
9
9
|
>('=');
|
|
10
10
|
|
|
11
11
|
expectType<
|
|
12
|
-
HasKeyReturnType<Readonly<{ a: 0 }
|
|
12
|
+
HasKeyReturnType<Readonly<{ a: 0 } | { b: 1 }>, 'b'>,
|
|
13
13
|
Readonly<{ b: 1 }>
|
|
14
14
|
>('=');
|
|
15
15
|
|
|
16
|
-
expectType<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
>('=');
|
|
16
|
+
expectType<HasKeyReturnType<Readonly<{ a: 0 } | { b: 1 }>, 'd'>, never>(
|
|
17
|
+
'=',
|
|
18
|
+
);
|
|
20
19
|
|
|
21
20
|
expectType<
|
|
22
21
|
HasKeyReturnType<
|
|
23
|
-
|
|
24
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
25
|
-
| Readonly<{ b: 2 }>
|
|
26
|
-
| Readonly<{ c: 3 }>,
|
|
22
|
+
Readonly<{ a: 0 } | { a: 1; b: 1 } | { b: 2 } | { c: 3 }>,
|
|
27
23
|
'a'
|
|
28
24
|
>,
|
|
29
|
-
Readonly<{ a: 0 }
|
|
25
|
+
Readonly<{ a: 0 } | { a: 1; b: 1 }>
|
|
30
26
|
>('=');
|
|
31
27
|
|
|
32
28
|
expectType<
|
|
33
29
|
HasKeyReturnType<
|
|
34
|
-
|
|
35
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
36
|
-
| Readonly<{ b: 2 }>
|
|
37
|
-
| Readonly<{ c: 3 }>,
|
|
30
|
+
Readonly<{ a: 0 } | { a: 1; b: 1 } | { b: 2 } | { c: 3 }>,
|
|
38
31
|
'b'
|
|
39
32
|
>,
|
|
40
|
-
Readonly<{ a: 1; b: 1 }
|
|
33
|
+
Readonly<{ a: 1; b: 1 } | { b: 2 }>
|
|
41
34
|
>('=');
|
|
42
35
|
|
|
43
36
|
expectType<
|
|
44
37
|
HasKeyReturnType<
|
|
45
38
|
| ReadonlyRecord<string, number>
|
|
46
|
-
| Readonly<{ a: 0 }
|
|
47
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
48
|
-
| Readonly<{ b: 2 }>,
|
|
39
|
+
| Readonly<{ a: 0 } | { a: 1; b: 1 } | { b: 2 }>,
|
|
49
40
|
'a'
|
|
50
41
|
>,
|
|
51
|
-
| Readonly<{ a: 0 }>
|
|
52
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
42
|
+
| Readonly<{ a: 0 } | { a: 1; b: 1 }>
|
|
53
43
|
| (ReadonlyRecord<'a', number> & ReadonlyRecord<string, number>)
|
|
54
44
|
>('=');
|
|
55
45
|
|
|
@@ -60,7 +50,7 @@ test('hasKey type inferences', () => {
|
|
|
60
50
|
}
|
|
61
51
|
|
|
62
52
|
{
|
|
63
|
-
type R = Readonly<{ a: 0 }
|
|
53
|
+
type R = Readonly<{ a: 0 } | { b: 1 }>;
|
|
64
54
|
|
|
65
55
|
const obj: R = { a: 0 } as R;
|
|
66
56
|
|
|
@@ -76,11 +66,7 @@ test('hasKey type inferences', () => {
|
|
|
76
66
|
}
|
|
77
67
|
|
|
78
68
|
{
|
|
79
|
-
type R =
|
|
80
|
-
| Readonly<{ a: 0 }>
|
|
81
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
82
|
-
| Readonly<{ b: 2 }>
|
|
83
|
-
| Readonly<{ c: 3 }>;
|
|
69
|
+
type R = Readonly<{ a: 0 } | { a: 1; b: 1 } | { b: 2 } | { c: 3 }>;
|
|
84
70
|
|
|
85
71
|
const obj: R = { a: 0 } as R;
|
|
86
72
|
|
|
@@ -96,18 +82,14 @@ test('hasKey type inferences', () => {
|
|
|
96
82
|
{
|
|
97
83
|
type R =
|
|
98
84
|
| ReadonlyRecord<string, number>
|
|
99
|
-
| Readonly<{ a: 0 }
|
|
100
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
101
|
-
| Readonly<{ b: 2 }>;
|
|
85
|
+
| Readonly<{ a: 0 } | { a: 1; b: 1 } | { b: 2 }>;
|
|
102
86
|
|
|
103
87
|
const obj: R = { a: 0 } as R;
|
|
104
88
|
|
|
105
89
|
expectType<
|
|
106
90
|
R,
|
|
107
91
|
| ReadonlyRecord<string, number>
|
|
108
|
-
| Readonly<{ a: 0 }>
|
|
109
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
110
|
-
| Readonly<{ b: 2 }>
|
|
92
|
+
| Readonly<{ a: 0 } | { a: 1; b: 1 } | { b: 2 }>
|
|
111
93
|
>('=');
|
|
112
94
|
|
|
113
95
|
if (hasKey(obj, 'a')) {
|
|
@@ -115,8 +97,7 @@ test('hasKey type inferences', () => {
|
|
|
115
97
|
|
|
116
98
|
expectType<
|
|
117
99
|
typeof obj,
|
|
118
|
-
| Readonly<{ a: 0 }>
|
|
119
|
-
| Readonly<{ a: 1; b: 1 }>
|
|
100
|
+
| Readonly<{ a: 0 } | { a: 1; b: 1 }>
|
|
120
101
|
| (ReadonlyRecord<'a', number> & ReadonlyRecord<string, number>)
|
|
121
102
|
>('=');
|
|
122
103
|
}
|
|
@@ -43,7 +43,7 @@ describe('isError from @sindresorhus/is', () => {
|
|
|
43
43
|
|
|
44
44
|
test('should return true for Error subclass with additional properties', () => {
|
|
45
45
|
class ExtendedError extends Error {
|
|
46
|
-
code: number;
|
|
46
|
+
readonly code: number;
|
|
47
47
|
|
|
48
48
|
constructor(message: string, code: number) {
|
|
49
49
|
super(message);
|
package/src/guard/is-record.mts
CHANGED
|
@@ -25,7 +25,7 @@ import { isNonNullObject } from './is-non-null-object.mjs';
|
|
|
25
25
|
* @example
|
|
26
26
|
*
|
|
27
27
|
* ```ts
|
|
28
|
-
* const entries: unknown[] = [{ id: 1 }, 'str', 0, null];
|
|
28
|
+
* const entries: readonly unknown[] = [{ id: 1 }, 'str', 0, null];
|
|
29
29
|
*
|
|
30
30
|
* const records = entries.filter(isRecord);
|
|
31
31
|
*
|
package/src/guard/is-type.mts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @example
|
|
10
10
|
*
|
|
11
11
|
* ```ts
|
|
12
|
-
* const values: (number | undefined)[] = [1, undefined, 2];
|
|
12
|
+
* const values: readonly (number | undefined)[] = [1, undefined, 2];
|
|
13
13
|
*
|
|
14
14
|
* const undefinedValues = values.filter(isUndefined);
|
|
15
15
|
*
|
|
@@ -34,7 +34,7 @@ export const isUndefined = (u: unknown): u is undefined => u === undefined;
|
|
|
34
34
|
* @example
|
|
35
35
|
*
|
|
36
36
|
* ```ts
|
|
37
|
-
* const values: (number | undefined)[] = [1, undefined, 2];
|
|
37
|
+
* const values: readonly (number | undefined)[] = [1, undefined, 2];
|
|
38
38
|
*
|
|
39
39
|
* const definedValues = values.filter(isNotUndefined);
|
|
40
40
|
*
|
|
@@ -60,7 +60,7 @@ export const isNotUndefined = <T,>(u: T): u is RelaxedExclude<T, undefined> =>
|
|
|
60
60
|
* @example
|
|
61
61
|
*
|
|
62
62
|
* ```ts
|
|
63
|
-
* const flags: unknown[] = [true, 'no', false];
|
|
63
|
+
* const flags: readonly unknown[] = [true, 'no', false];
|
|
64
64
|
*
|
|
65
65
|
* const booleans = flags.filter(isBoolean);
|
|
66
66
|
*
|
|
@@ -84,7 +84,7 @@ export const isBoolean = (u: unknown): u is boolean => typeof u === 'boolean';
|
|
|
84
84
|
* @example
|
|
85
85
|
*
|
|
86
86
|
* ```ts
|
|
87
|
-
* const flags: unknown[] = [true, 'no', false];
|
|
87
|
+
* const flags: readonly unknown[] = [true, 'no', false];
|
|
88
88
|
*
|
|
89
89
|
* const nonBooleans = flags.filter(isNotBoolean);
|
|
90
90
|
*
|
|
@@ -111,7 +111,7 @@ export const isNotBoolean = <T,>(u: T): u is RelaxedExclude<T, boolean> =>
|
|
|
111
111
|
* @example
|
|
112
112
|
*
|
|
113
113
|
* ```ts
|
|
114
|
-
* const mixed: unknown[] = [1, '2', 3];
|
|
114
|
+
* const mixed: readonly unknown[] = [1, '2', 3];
|
|
115
115
|
*
|
|
116
116
|
* const numbers = mixed.filter(isNumber);
|
|
117
117
|
*
|
|
@@ -135,7 +135,7 @@ export const isNumber = (u: unknown): u is number => typeof u === 'number';
|
|
|
135
135
|
* @example
|
|
136
136
|
*
|
|
137
137
|
* ```ts
|
|
138
|
-
* const mixed: unknown[] = [1, '2', 3];
|
|
138
|
+
* const mixed: readonly unknown[] = [1, '2', 3];
|
|
139
139
|
*
|
|
140
140
|
* const nonNumbers = mixed.filter(isNotNumber);
|
|
141
141
|
*
|
|
@@ -161,7 +161,7 @@ export const isNotNumber = <T,>(u: T): u is RelaxedExclude<T, number> =>
|
|
|
161
161
|
* @example
|
|
162
162
|
*
|
|
163
163
|
* ```ts
|
|
164
|
-
* const values: unknown[] = [1n, 2, 3n];
|
|
164
|
+
* const values: readonly unknown[] = [1n, 2, 3n];
|
|
165
165
|
*
|
|
166
166
|
* const bigints = values.filter(isBigint);
|
|
167
167
|
*
|
|
@@ -185,7 +185,7 @@ export const isBigint = (u: unknown): u is bigint => typeof u === 'bigint';
|
|
|
185
185
|
* @example
|
|
186
186
|
*
|
|
187
187
|
* ```ts
|
|
188
|
-
* const values: unknown[] = [1n, 2, 3n];
|
|
188
|
+
* const values: readonly unknown[] = [1n, 2, 3n];
|
|
189
189
|
*
|
|
190
190
|
* const nonBigints = values.filter(isNotBigint);
|
|
191
191
|
*
|
|
@@ -212,7 +212,7 @@ export const isNotBigint = <T,>(u: T): u is RelaxedExclude<T, bigint> =>
|
|
|
212
212
|
* @example
|
|
213
213
|
*
|
|
214
214
|
* ```ts
|
|
215
|
-
* const values: unknown[] = ['Ada', 42, 'Lovelace'];
|
|
215
|
+
* const values: readonly unknown[] = ['Ada', 42, 'Lovelace'];
|
|
216
216
|
*
|
|
217
217
|
* const strings = values.filter(isString);
|
|
218
218
|
*
|
|
@@ -236,7 +236,7 @@ export const isString = (u: unknown): u is string => typeof u === 'string';
|
|
|
236
236
|
* @example
|
|
237
237
|
*
|
|
238
238
|
* ```ts
|
|
239
|
-
* const values: unknown[] = ['Ada', 42, 'Lovelace'];
|
|
239
|
+
* const values: readonly unknown[] = ['Ada', 42, 'Lovelace'];
|
|
240
240
|
*
|
|
241
241
|
* const nonStrings = values.filter(isNotString);
|
|
242
242
|
*
|
|
@@ -266,7 +266,7 @@ export const isNotString = <T,>(u: T): u is RelaxedExclude<T, string> =>
|
|
|
266
266
|
*
|
|
267
267
|
* const shared = Symbol.for('shared');
|
|
268
268
|
*
|
|
269
|
-
* const tokens: unknown[] = [id, 'shared', shared];
|
|
269
|
+
* const tokens: readonly unknown[] = [id, 'shared', shared];
|
|
270
270
|
*
|
|
271
271
|
* const symbols = tokens.filter(isSymbol);
|
|
272
272
|
*
|
|
@@ -292,7 +292,7 @@ export const isSymbol = (u: unknown): u is symbol => typeof u === 'symbol';
|
|
|
292
292
|
* ```ts
|
|
293
293
|
* const id = Symbol('id');
|
|
294
294
|
*
|
|
295
|
-
* const tokens: unknown[] = [id, 'shared'];
|
|
295
|
+
* const tokens: readonly unknown[] = [id, 'shared'];
|
|
296
296
|
*
|
|
297
297
|
* const nonSymbols = tokens.filter(isNotSymbol);
|
|
298
298
|
*
|
|
@@ -343,7 +343,7 @@ export const isNull = (u: unknown): u is null => u === null;
|
|
|
343
343
|
* @example
|
|
344
344
|
*
|
|
345
345
|
* ```ts
|
|
346
|
-
* const values: (number | null)[] = [null, 5];
|
|
346
|
+
* const values: readonly (number | null)[] = [null, 5];
|
|
347
347
|
*
|
|
348
348
|
* const nonNullValues = values.filter(isNotNull);
|
|
349
349
|
*
|
|
@@ -372,7 +372,11 @@ export const isNotNull = <T,>(u: T | null): u is T => u !== null;
|
|
|
372
372
|
* @example
|
|
373
373
|
*
|
|
374
374
|
* ```ts
|
|
375
|
-
* const values: (string | null | undefined)[] = [
|
|
375
|
+
* const values: readonly (string | null | undefined)[] = [
|
|
376
|
+
* 'Ada',
|
|
377
|
+
* null,
|
|
378
|
+
* undefined,
|
|
379
|
+
* ];
|
|
376
380
|
*
|
|
377
381
|
* const nullishValues = values.filter(isNullish);
|
|
378
382
|
*
|
|
@@ -401,7 +405,11 @@ export const isNullish = (u: unknown): u is null | undefined => u == null;
|
|
|
401
405
|
* @example
|
|
402
406
|
*
|
|
403
407
|
* ```ts
|
|
404
|
-
* const values: (string | null | undefined)[] = [
|
|
408
|
+
* const values: readonly (string | null | undefined)[] = [
|
|
409
|
+
* 'Ada',
|
|
410
|
+
* null,
|
|
411
|
+
* undefined,
|
|
412
|
+
* ];
|
|
405
413
|
*
|
|
406
414
|
* const definedValues = values.filter(isNonNullish);
|
|
407
415
|
*
|
|
@@ -566,7 +566,7 @@ describe(isNonNullish, () => {
|
|
|
566
566
|
});
|
|
567
567
|
|
|
568
568
|
test('should work with array filtering', () => {
|
|
569
|
-
const items: (string | null | undefined)[] = [
|
|
569
|
+
const items: readonly (string | null | undefined)[] = [
|
|
570
570
|
'hello',
|
|
571
571
|
null,
|
|
572
572
|
'world',
|
|
@@ -576,7 +576,7 @@ describe(isNonNullish, () => {
|
|
|
576
576
|
|
|
577
577
|
const definedItems = items.filter(isNonNullish);
|
|
578
578
|
|
|
579
|
-
expectType<typeof definedItems, string[]>('<=');
|
|
579
|
+
expectType<typeof definedItems, readonly string[]>('<=');
|
|
580
580
|
|
|
581
581
|
expect(definedItems).toHaveLength(3);
|
|
582
582
|
|
|
@@ -609,7 +609,7 @@ describe('type guard behavior in complex scenarios', () => {
|
|
|
609
609
|
});
|
|
610
610
|
|
|
611
611
|
test('should work with array operations', () => {
|
|
612
|
-
const mixed: (string | number | boolean | null | undefined)[] = [
|
|
612
|
+
const mixed: readonly (string | number | boolean | null | undefined)[] = [
|
|
613
613
|
'hello',
|
|
614
614
|
42,
|
|
615
615
|
true,
|
|
@@ -622,15 +622,15 @@ describe('type guard behavior in complex scenarios', () => {
|
|
|
622
622
|
|
|
623
623
|
const nonNullish = mixed.filter(isNonNullish);
|
|
624
624
|
|
|
625
|
-
expectType<typeof nonNullish, (string | number | boolean)[]>('<=');
|
|
625
|
+
expectType<typeof nonNullish, readonly (string | number | boolean)[]>('<=');
|
|
626
626
|
|
|
627
627
|
const nonBooleans = nonNullish.filter(isNotBoolean);
|
|
628
628
|
|
|
629
|
-
expectType<typeof nonBooleans, (string | number)[]>('<=');
|
|
629
|
+
expectType<typeof nonBooleans, readonly (string | number)[]>('<=');
|
|
630
630
|
|
|
631
631
|
const strings = nonBooleans.filter(isNotNumber);
|
|
632
632
|
|
|
633
|
-
expectType<typeof strings, string[]>('<=');
|
|
633
|
+
expectType<typeof strings, readonly string[]>('<=');
|
|
634
634
|
|
|
635
635
|
assert.deepStrictEqual(strings, ['hello', 'world']);
|
|
636
636
|
});
|
package/src/json/json.test.mts
CHANGED
|
@@ -507,6 +507,7 @@ describe('stringifySelected', () => {
|
|
|
507
507
|
});
|
|
508
508
|
|
|
509
509
|
test('should handle circular references with error', () => {
|
|
510
|
+
// transformer-ignore-next-line
|
|
510
511
|
type CircularType = { name: string; self?: CircularType };
|
|
511
512
|
|
|
512
513
|
const mut_circular: CircularType = { name: 'test' };
|
|
@@ -669,6 +670,7 @@ describe('stringifySortedKey', () => {
|
|
|
669
670
|
|
|
670
671
|
test('should handle problematic objects', () => {
|
|
671
672
|
try {
|
|
673
|
+
// transformer-ignore-next-line
|
|
672
674
|
type CircularObj = {
|
|
673
675
|
normal: string;
|
|
674
676
|
circular: { self?: CircularObj };
|