utilitish 0.0.6 → 0.0.7

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.
@@ -0,0 +1,536 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./array-prototype");
4
+ describe('Array.prototype', () => {
5
+ describe('first()', () => {
6
+ it('should return first element of non-empty array', () => {
7
+ expect([1, 2, 3].first()).toBe(1);
8
+ });
9
+ it('should return undefined for empty array', () => {
10
+ expect([].first()).toBe(undefined);
11
+ });
12
+ });
13
+ describe('last()', () => {
14
+ it('should return last element of non-empty array', () => {
15
+ expect([1, 2, 3].last()).toBe(3);
16
+ });
17
+ it('should return undefined for empty array', () => {
18
+ expect([].last()).toBe(undefined);
19
+ });
20
+ });
21
+ describe('sum()', () => {
22
+ describe('with number arrays', () => {
23
+ it('should return sum of all numbers', () => {
24
+ expect([1, 2, 3].sum()).toBe(6);
25
+ });
26
+ it('should return 0 for empty array', () => {
27
+ expect([].sum()).toBe(0);
28
+ });
29
+ it('should return 0 when array contains only 0', () => {
30
+ expect([0].sum()).toBe(0);
31
+ });
32
+ });
33
+ describe('with selector function', () => {
34
+ it('should return the sum when using selector function', () => {
35
+ const items = [{ x: 1 }, { x: 2 }];
36
+ expect(items.sum((item) => item.x)).toBe(3);
37
+ });
38
+ });
39
+ describe('with selector string key', () => {
40
+ it('should return the sum when using property key', () => {
41
+ const items = [{ x: 1 }, { x: 2 }];
42
+ expect(items.sum('x')).toBe(3);
43
+ });
44
+ });
45
+ describe('error handling', () => {
46
+ it('should throw TypeError when called on non-number array without selector', () => {
47
+ const items = [{ x: 2 }, { x: 4 }];
48
+ expect(() => items.sum()).toThrow(TypeError);
49
+ });
50
+ });
51
+ });
52
+ describe('average()', () => {
53
+ describe('with number arrays', () => {
54
+ it('should return average of all numbers', () => {
55
+ expect([2, 4, 6].average()).toBe(4);
56
+ });
57
+ it('should return 0 for empty array', () => {
58
+ expect([].average()).toBe(0);
59
+ });
60
+ });
61
+ describe('with selector function', () => {
62
+ it('should return the average when using selector function', () => {
63
+ const items = [{ x: 2 }, { x: 4 }];
64
+ expect(items.average((item) => item.x)).toBe(3);
65
+ });
66
+ });
67
+ describe('with selector string key', () => {
68
+ it('should return the average when using property key', () => {
69
+ const items = [{ x: 2 }, { x: 4 }];
70
+ expect(items.average('x')).toBe(3);
71
+ });
72
+ });
73
+ describe('error handling', () => {
74
+ it('should throw TypeError when called on non-number array without selector', () => {
75
+ const items = [{ x: 2 }, { x: 4 }];
76
+ expect(() => items.average()).toThrow(TypeError);
77
+ });
78
+ });
79
+ });
80
+ describe('unique()', () => {
81
+ it('should return array with unique values', () => {
82
+ expect([1, 1, 2, 2, 3].unique()).toEqual([1, 2, 3]);
83
+ });
84
+ });
85
+ describe('chunk()', () => {
86
+ describe('with valid size', () => {
87
+ it('should split array into chunks of even elements', () => {
88
+ expect([1, 2, 3, 4].chunk(2)).toEqual([
89
+ [1, 2],
90
+ [3, 4],
91
+ ]);
92
+ });
93
+ it('should include partial chunk at end when array does not divide evenly', () => {
94
+ expect([1, 2, 3].chunk(2)).toEqual([[1, 2], [3]]);
95
+ });
96
+ });
97
+ describe('error handling', () => {
98
+ it('should throw TypeError when size is not a positive integer', () => {
99
+ const arr = [1, 2, 3];
100
+ expect(() => arr.chunk(0)).toThrow(TypeError);
101
+ expect(() => arr.chunk(-1)).toThrow(TypeError);
102
+ expect(() => arr.chunk(1.5)).toThrow(TypeError);
103
+ expect(() => arr.chunk('a')).toThrow(TypeError);
104
+ });
105
+ });
106
+ });
107
+ describe('groupBy()', () => {
108
+ it('should group by property key', () => {
109
+ const arr = [
110
+ { type: 'a', value: 1 },
111
+ { type: 'b', value: 2 },
112
+ { type: 'a', value: 3 },
113
+ ];
114
+ const map = arr.groupBy('type');
115
+ expect(map instanceof Map).toBe(true);
116
+ expect(map.get('a')).toEqual([
117
+ { type: 'a', value: 1 },
118
+ { type: 'a', value: 3 },
119
+ ]);
120
+ expect(map.get('b')).toEqual([{ type: 'b', value: 2 }]);
121
+ });
122
+ it('should group by selector function', () => {
123
+ const arr = [1, 2, 3, 4, 5, 6];
124
+ const map = arr.groupBy((x) => (x % 2 === 0 ? 'even' : 'odd'));
125
+ expect(map instanceof Map).toBe(true);
126
+ expect(map.get('even')).toEqual([2, 4, 6]);
127
+ expect(map.get('odd')).toEqual([1, 3, 5]);
128
+ });
129
+ it('should return an empty Map when array is empty', () => {
130
+ expect([].groupBy((x) => x)).toEqual(new Map());
131
+ });
132
+ });
133
+ describe('compact()', () => {
134
+ it('should remove all falsy values', () => {
135
+ expect([0, 1, false, 2, '', 3, null].compact()).toEqual([1, 2, 3]);
136
+ });
137
+ });
138
+ describe('enumerate()', () => {
139
+ it('should return array of [value, index] tuples', () => {
140
+ const result = ['a', 'b', 'c'].enumerate();
141
+ expect(result).toEqual([
142
+ ['a', 0],
143
+ ['b', 1],
144
+ ['c', 2],
145
+ ]);
146
+ });
147
+ });
148
+ describe('sortAsc()', () => {
149
+ describe('with primitive arrays', () => {
150
+ it('should sort numbers in ascending order', () => {
151
+ expect([3, 1, 2].sortAsc()).toEqual([1, 2, 3]);
152
+ });
153
+ it('should sort strings in ascending order', () => {
154
+ expect(['b', 'a', 'c'].sortAsc()).toEqual(['a', 'b', 'c']);
155
+ });
156
+ it('should return empty array when empty', () => {
157
+ expect([].sortAsc()).toEqual([]);
158
+ });
159
+ });
160
+ describe('with selector function', () => {
161
+ it('should sort using selector function', () => {
162
+ const arr = [{ v: 2 }, { v: 1 }];
163
+ expect(arr.sortAsc((x) => x.v)).toEqual([{ v: 1 }, { v: 2 }]);
164
+ });
165
+ });
166
+ describe('with selector string key', () => {
167
+ it('should sort using property key', () => {
168
+ const arr = [{ v: 2 }, { v: 1 }];
169
+ expect(arr.sortAsc('v')).toEqual([{ v: 1 }, { v: 2 }]);
170
+ });
171
+ });
172
+ describe('error handling', () => {
173
+ it('should throw TypeError when selector returns non-sortable type', () => {
174
+ expect(() => [{ v: {} }, { v: {} }].sortAsc((x) => x.v)).toThrow(TypeError);
175
+ });
176
+ it('should throw TypeError when elements are not sortable without selector', () => {
177
+ expect(() => [{ v: 1 }].sortAsc()).toThrow(TypeError);
178
+ });
179
+ });
180
+ });
181
+ describe('sortDesc()', () => {
182
+ describe('with primitive arrays', () => {
183
+ it('should sort numbers in descending order', () => {
184
+ expect([1, 3, 2, 4].sortDesc()).toEqual([4, 3, 2, 1]);
185
+ });
186
+ it('should sort strings in descending order', () => {
187
+ expect(['b', 'a', 'c'].sortDesc()).toEqual(['c', 'b', 'a']);
188
+ });
189
+ it('should return empty array when empty', () => {
190
+ expect([].sortDesc()).toEqual([]);
191
+ });
192
+ });
193
+ describe('with selector function', () => {
194
+ it('should sort using selector function', () => {
195
+ const arr = [{ v: 1 }, { v: 2 }];
196
+ expect(arr.sortDesc((x) => x.v)).toEqual([{ v: 2 }, { v: 1 }]);
197
+ });
198
+ });
199
+ describe('with selector string key', () => {
200
+ it('should sort using property key', () => {
201
+ const arr = [{ v: 1 }, { v: 2 }];
202
+ expect(arr.sortDesc('v')).toEqual([{ v: 2 }, { v: 1 }]);
203
+ });
204
+ });
205
+ describe('error handling', () => {
206
+ it('should throw TypeError when selector returns non-sortable type', () => {
207
+ expect(() => [{ v: {} }, { v: {} }].sortDesc((x) => x.v)).toThrow(TypeError);
208
+ });
209
+ it('should throw TypeError when elements are not sortable without selector', () => {
210
+ expect(() => [{ v: 1 }].sortDesc()).toThrow(TypeError);
211
+ });
212
+ });
213
+ });
214
+ describe('swap()', () => {
215
+ describe('with valid indices', () => {
216
+ it('should swap two elements at given indices', () => {
217
+ const arr = [1, 2, 3];
218
+ arr.swap(0, 2);
219
+ expect(arr).toEqual([3, 2, 1]);
220
+ });
221
+ it('should do nothing when indices are identical', () => {
222
+ const arr = [1, 2, 3];
223
+ arr.swap(1, 1);
224
+ expect(arr).toEqual([1, 2, 3]);
225
+ });
226
+ });
227
+ describe('error handling', () => {
228
+ it('should throw RangeError when index is out of bounds', () => {
229
+ const arr = [1, 2, 3];
230
+ expect(() => arr.swap(-1, 2)).toThrow(RangeError);
231
+ expect(() => arr.swap(0, 3)).toThrow(RangeError);
232
+ });
233
+ it('should throw TypeError when indices are not integers', () => {
234
+ const arr = [1, 2, 3];
235
+ expect(() => arr.swap(0.5, 2)).toThrow(TypeError);
236
+ expect(() => arr.swap(0, 'a')).toThrow(TypeError);
237
+ });
238
+ });
239
+ });
240
+ describe('shuffle()', () => {
241
+ it('should return a new array with same elements in different order', () => {
242
+ const arr = [1, 2, 3, 4, 5];
243
+ const shuffled = arr.shuffle();
244
+ expect(shuffled).toHaveLength(arr.length);
245
+ expect(shuffled.sort()).toEqual(arr.sort());
246
+ });
247
+ it('should not mutate the original array', () => {
248
+ const arr = [1, 2, 3];
249
+ const copy = arr.slice();
250
+ arr.shuffle();
251
+ expect(arr).toEqual(copy);
252
+ });
253
+ it('should return a new array instance', () => {
254
+ const arr = [1, 2, 3];
255
+ const shuffled = arr.shuffle();
256
+ expect(shuffled).not.toBe(arr);
257
+ });
258
+ it('should return an empty array when called on empty array', () => {
259
+ expect([].shuffle()).toEqual([]);
260
+ });
261
+ });
262
+ describe('toMap()', () => {
263
+ describe('with pairs array', () => {
264
+ it('should convert array of pairs to Map', () => {
265
+ const arr = [
266
+ ['a', 1],
267
+ ['b', 2],
268
+ ];
269
+ const map = arr.toMap();
270
+ expect(map instanceof Map).toBe(true);
271
+ expect(map.size).toBe(2);
272
+ expect(map.get('a')).toBe(1);
273
+ expect(map.get('b')).toBe(2);
274
+ });
275
+ });
276
+ describe('with selector string key and no value selector', () => {
277
+ it('should convert array of objects using property key', () => {
278
+ const arr = [
279
+ { id: 1, name: 'foo' },
280
+ { id: 2, name: 'bar' },
281
+ ];
282
+ const map = arr.toMap('id');
283
+ expect(map instanceof Map).toBe(true);
284
+ expect(map.size).toBe(2);
285
+ expect(map.get(1)).toEqual({ id: 1, name: 'foo' });
286
+ expect(map.get(2)).toEqual({ id: 2, name: 'bar' });
287
+ });
288
+ });
289
+ describe('with selector functions', () => {
290
+ it('should convert array using key and value selectors', () => {
291
+ const arr = [
292
+ { id: 1, name: 'foo' },
293
+ { id: 2, name: 'bar' },
294
+ ];
295
+ const map = arr.toMap((x) => x.id, (x) => x.name);
296
+ expect(map instanceof Map).toBe(true);
297
+ expect(map.size).toBe(2);
298
+ expect(map.get(1)).toBe('foo');
299
+ expect(map.get(2)).toBe('bar');
300
+ });
301
+ it('should convert array using key selector only', () => {
302
+ const arr = [
303
+ { id: 1, name: 'foo' },
304
+ { id: 2, name: 'bar' },
305
+ ];
306
+ const map = arr.toMap((x) => x.id);
307
+ expect(map instanceof Map).toBe(true);
308
+ expect(map.size).toBe(2);
309
+ expect(map.get(1)).toEqual({ id: 1, name: 'foo' });
310
+ expect(map.get(2)).toEqual({ id: 2, name: 'bar' });
311
+ });
312
+ it('should convert array using string key and value selector', () => {
313
+ const arr = [
314
+ { id: 1, name: 'foo' },
315
+ { id: 2, name: 'bar' },
316
+ ];
317
+ const map = arr.toMap('id', (x) => x.name);
318
+ expect(map instanceof Map).toBe(true);
319
+ expect(map.size).toBe(2);
320
+ expect(map.get(1)).toBe('foo');
321
+ expect(map.get(2)).toBe('bar');
322
+ });
323
+ });
324
+ describe('with no selectors', () => {
325
+ it('should use index as key', () => {
326
+ const arr = [
327
+ { id: 1, name: 'foo' },
328
+ { id: 2, name: 'bar' },
329
+ ];
330
+ const map = arr.toMap();
331
+ expect(map instanceof Map).toBe(true);
332
+ expect(map.size).toBe(2);
333
+ expect(map.get(0)).toEqual({ id: 1, name: 'foo' });
334
+ expect(map.get(1)).toEqual({ id: 2, name: 'bar' });
335
+ });
336
+ });
337
+ describe('error handling', () => {
338
+ it('should throw Error when key selector is invalid', () => {
339
+ expect(() => [{ id: 1 }].toMap(123)).toThrow(Error);
340
+ });
341
+ });
342
+ });
343
+ describe('toSet()', () => {
344
+ describe('without selector', () => {
345
+ it('should return Set of unique elements', () => {
346
+ expect([1, 2, 2, 3].toSet()).toEqual(new Set([1, 2, 3]));
347
+ });
348
+ it('should return empty Set when array is empty', () => {
349
+ expect([].toSet()).toEqual(new Set());
350
+ });
351
+ });
352
+ describe('with selector function', () => {
353
+ it('should return Set of selected values', () => {
354
+ const arr = [{ id: 1 }, { id: 2 }, { id: 1 }];
355
+ expect(arr.toSet((x) => x.id)).toEqual(new Set([1, 2]));
356
+ });
357
+ });
358
+ describe('with selector string key', () => {
359
+ it('should return Set of property key values', () => {
360
+ const arr = [{ id: 1 }, { id: 2 }, { id: 1 }];
361
+ expect(arr.toSet('id')).toEqual(new Set([1, 2]));
362
+ });
363
+ });
364
+ });
365
+ describe('countBy()', () => {
366
+ describe('without selector', () => {
367
+ it('should count elements directly', () => {
368
+ const arr = ['a', 'b', 'a', 'c', 'b', 'a'];
369
+ expect(arr.countBy()).toEqual(new Map([
370
+ ['a', 3],
371
+ ['b', 2],
372
+ ['c', 1],
373
+ ]));
374
+ });
375
+ it('should return empty Map when array is empty', () => {
376
+ expect([].countBy((x) => x)).toEqual(new Map());
377
+ });
378
+ });
379
+ describe('with selector function', () => {
380
+ it('should count elements by selector result', () => {
381
+ const arr = ['a', 'b', 'a', 'c', 'b', 'a'];
382
+ expect(arr.countBy((x) => x)).toEqual(new Map([
383
+ ['a', 3],
384
+ ['b', 2],
385
+ ['c', 1],
386
+ ]));
387
+ });
388
+ it('should count objects by extracted value', () => {
389
+ const arr = [{ type: 'x' }, { type: 'y' }, { type: 'x' }];
390
+ expect(arr.countBy((x) => x.type)).toEqual(new Map([
391
+ ['x', 2],
392
+ ['y', 1],
393
+ ]));
394
+ });
395
+ });
396
+ describe('with selector string key', () => {
397
+ it('should count objects by property key', () => {
398
+ const arr = [{ type: 'x' }, { type: 'y' }, { type: 'x' }];
399
+ expect(arr.countBy('type')).toEqual(new Map([
400
+ ['x', 2],
401
+ ['y', 1],
402
+ ]));
403
+ });
404
+ });
405
+ describe('error handling', () => {
406
+ it('should throw Error for invalid selector', () => {
407
+ expect(() => [{ id: 1 }].toMap(123)).toThrow(Error);
408
+ });
409
+ });
410
+ });
411
+ describe('Array.prototype.toObject', () => {
412
+ it('converts array of pairs to object', () => {
413
+ const arr = [
414
+ ['a', 1],
415
+ ['b', 2],
416
+ ['c', 3],
417
+ ];
418
+ const obj = arr.toObject();
419
+ expect(obj).toEqual({ a: 1, b: 2, c: 3 });
420
+ expect(typeof obj).toBe('object');
421
+ });
422
+ it('converts array of pairs with numeric keys to object', () => {
423
+ const arr = [
424
+ [1, 'a'],
425
+ [2, 'b'],
426
+ [3, 'c'],
427
+ ];
428
+ const obj = arr.toObject();
429
+ expect(obj).toEqual({ 1: 'a', 2: 'b', 3: 'c' });
430
+ });
431
+ it('converts array of objects to object using key string', () => {
432
+ const arr = [
433
+ { id: 1, name: 'foo' },
434
+ { id: 2, name: 'bar' },
435
+ ];
436
+ const obj = arr.toObject('id');
437
+ expect(obj).toEqual({
438
+ 1: { id: 1, name: 'foo' },
439
+ 2: { id: 2, name: 'bar' },
440
+ });
441
+ });
442
+ it('converts array of objects to object using key callback', () => {
443
+ const arr = [
444
+ { id: 1, name: 'foo' },
445
+ { id: 2, name: 'bar' },
446
+ ];
447
+ const obj = arr.toObject((x) => x.id);
448
+ expect(obj).toEqual({
449
+ 1: { id: 1, name: 'foo' },
450
+ 2: { id: 2, name: 'bar' },
451
+ });
452
+ });
453
+ it('converts array of objects using key callback and value callback', () => {
454
+ const arr = [
455
+ { id: 1, name: 'foo' },
456
+ { id: 2, name: 'bar' },
457
+ ];
458
+ const obj = arr.toObject((x) => x.id, (x) => x.name);
459
+ expect(obj).toEqual({
460
+ 1: 'foo',
461
+ 2: 'bar',
462
+ });
463
+ });
464
+ it('converts array without selector (uses index as key)', () => {
465
+ const arr = ['a', 'b', 'c'];
466
+ const obj = arr.toObject();
467
+ expect(obj).toEqual({
468
+ 0: 'a',
469
+ 1: 'b',
470
+ 2: 'c',
471
+ });
472
+ });
473
+ it('converts empty array to empty object', () => {
474
+ const arr = [];
475
+ const obj = arr.toObject();
476
+ expect(obj).toEqual({});
477
+ });
478
+ it('handles objects with string and numeric keys', () => {
479
+ const arr = [
480
+ { key: 'name', value: 'Alice' },
481
+ { key: 'age', value: 30 },
482
+ ];
483
+ const obj = arr.toObject((x) => x.key, (x) => x.value);
484
+ expect(obj).toEqual({
485
+ name: 'Alice',
486
+ age: 30,
487
+ });
488
+ });
489
+ it('throws error when key selector returns null', () => {
490
+ const arr = [{ id: 1, name: 'foo' }];
491
+ expect(() => arr.toObject((x) => null, (x) => x.name)).toThrow(TypeError);
492
+ });
493
+ it('throws error when key selector returns undefined', () => {
494
+ const arr = [{ id: 1, name: 'foo' }];
495
+ expect(() => arr.toObject((x) => undefined, (x) => x.name)).toThrow(TypeError);
496
+ });
497
+ it('throws error when key is not a string or number', () => {
498
+ const arr = [{ id: { nested: 1 }, name: 'foo' }];
499
+ expect(() => arr.toObject((x) => x.id)).toThrow(TypeError);
500
+ });
501
+ it('overwrites duplicate keys with the last value', () => {
502
+ const arr = [
503
+ { id: 1, value: 'first' },
504
+ { id: 1, value: 'second' },
505
+ ];
506
+ const obj = arr.toObject((x) => x.id, (x) => x.value);
507
+ expect(obj).toEqual({
508
+ 1: 'second',
509
+ });
510
+ });
511
+ it('handles mixed types in array', () => {
512
+ const arr = [
513
+ { id: 'x', value: 10 },
514
+ { id: 'y', value: 20 },
515
+ ];
516
+ const obj = arr.toObject((x) => x.id, (x) => x.value);
517
+ expect(obj).toEqual({
518
+ x: 10,
519
+ y: 20,
520
+ });
521
+ });
522
+ it('converts with string key and different value types', () => {
523
+ const arr = [
524
+ { id: 1, data: 'text' },
525
+ { id: 2, data: 42 },
526
+ { id: 3, data: null },
527
+ ];
528
+ const obj = arr.toObject('id', (x) => x.data);
529
+ expect(obj).toEqual({
530
+ 1: 'text',
531
+ 2: 42,
532
+ 3: null,
533
+ });
534
+ });
535
+ });
536
+ });
@@ -2,11 +2,28 @@ export {};
2
2
  declare global {
3
3
  interface Map<K, V> {
4
4
  /**
5
- * Converts the Map into a list or object, depending on the selected type.
6
- * - `entries` (default): returns `[K, V][]`
7
- * - `keys`: returns `K[]`
8
- * - `values`: returns `V[]`
9
- * - `object`: returns `{ [key: string]: V }`
5
+ * Converts the Map into a list or specific structure based on the selected conversion type.
6
+ * Supports multiple output formats: entries, keys, values, or a plain object.
7
+ *
8
+ * @template K The type of keys in the Map
9
+ * @template V The type of values in the Map
10
+ * @this {Map<K, V>} The Map to convert
11
+ * @param {string} [type='entries'] - The conversion type ('keys' | 'values' | 'entries' | 'object')
12
+ * @returns {any} Converted output as specified by the type parameter
13
+ * @throws {TypeError} If type is 'object' with non-compatible keys or if type is unknown
14
+ *
15
+ * @example
16
+ * const map = new Map([['a', 1], ['b', 2]]);
17
+ * map.toList(); // [['a', 1], ['b', 2]]
18
+ * map.toList('keys'); // ['a', 'b']
19
+ * map.toList('values'); // [1, 2]
20
+ * map.toList('object'); // { a: 1, b: 2 }
21
+ *
22
+ * @remarks
23
+ * - `entries` (default): Returns array of [K, V] pairs
24
+ * - `keys`: Returns array of all keys
25
+ * - `values`: Returns array of all values
26
+ * - `object`: Returns Record with string keys (requires keys to be string/number/symbol)
10
27
  */
11
28
  toList(type: 'keys'): K[];
12
29
  toList(type: 'values'): V[];
@@ -14,11 +31,54 @@ declare global {
14
31
  toList(type: 'entries'): [K, V][];
15
32
  toList(): [K, V][];
16
33
  /**
17
- * Ensures that the value for the given key is an array.
18
- * If the key does not exist, it sets it to an empty array.
34
+ * Converts a Map to a plain JavaScript object.
35
+ * Each key/value pair in the Map becomes a property/value in the resulting object.
36
+ * Validates that all keys are valid PropertyKey types.
37
+ *
38
+ * @template K Type of keys (must extend PropertyKey: string | number | symbol)
39
+ * @template V Type of values in the Map
40
+ * @this {Map<K, V>} The Map to convert
41
+ * @returns {Record<K, V>} A plain object with Map entries as properties
42
+ * @throws {TypeError} If any key is null, undefined, or not a PropertyKey type
43
+ *
44
+ * @example
45
+ * const map = new Map<string, number>([['a', 1], ['b', 2]]);
46
+ * map.toObject(); // { a: 1, b: 2 }
47
+ *
48
+ * const numKeyMap = new Map<number, string>([[1, 'one'], [2, 'two']]);
49
+ * numKeyMap.toObject(); // { 1: 'one', 2: 'two' }
50
+ *
51
+ * @remarks
52
+ * - Provides validation and error handling for property key compatibility
53
+ * - Supports string, number, and symbol keys
54
+ * - Returns a new object instance each time (no modification to original)
55
+ */
56
+ toObject<K extends PropertyKey, V>(this: Map<K, V>): Record<K, V>;
57
+ /**
58
+ * Ensures that the Map has an entry for the given key with an array as value.
59
+ * If the key doesn't exist, initializes it with an empty array.
60
+ * Validates that the existing value (if any) is indeed an array.
61
+ *
62
+ * @template K Type of keys in the Map
63
+ * @template L The array type stored as values (extends Array<any>)
64
+ * @this {Map<K, L>} The Map where values must be arrays
65
+ * @param {K} key - The key to look up or initialize
66
+ * @returns {L} The array associated with the key (either existing or newly created)
67
+ * @throws {TypeError} If key is null/undefined or if the existing value is not an array
68
+ *
69
+ * @example
70
+ * const map = new Map<string, number[]>();
71
+ * const arr1 = map.ensureArray('items'); // Returns [], and ['items'] => [] is set in map
72
+ * arr1.push(42);
73
+ *
74
+ * const arr2 = map.ensureArray('items'); // Returns same array with [42]
75
+ * arr1 === arr2; // true (same reference)
19
76
  *
20
- * @param key - The key to look up in the map.
21
- * @returns The array associated with the key.
77
+ * @remarks
78
+ * - Modifies the Map in place (lazy initialization pattern)
79
+ * - Useful for Maps that accumulate items by key
80
+ * - Throws if the existing value for a key is not an array
81
+ * - Key must not be null or undefined
22
82
  */
23
83
  ensureArray<L extends Array<any>>(this: Map<K, L>, key: K): L;
24
84
  }
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const utils_1 = require("../utils");
4
- (0, utils_1.defineIfNotExists)(Map.prototype, 'toList', function (type = 'entries') {
3
+ const core_utils_1 = require("../utils/core.utils");
4
+ const logic_utils_1 = require("../utils/logic.utils");
5
+ /**
6
+ * @see Map.prototype.toList
7
+ */
8
+ (0, core_utils_1.defineIfNotExists)(Map.prototype, 'toList', function (type = 'entries') {
5
9
  switch (type) {
6
10
  case 'keys':
7
11
  return Array.from(this.keys());
@@ -26,7 +30,16 @@ const utils_1 = require("../utils");
26
30
  throw new TypeError(`Unknown type "${type}" for Map.prototype.toList`);
27
31
  }
28
32
  });
29
- (0, utils_1.defineIfNotExists)(Map.prototype, 'ensureArray', function (key) {
33
+ /**
34
+ * @see Map.prototype.toObject
35
+ */
36
+ (0, core_utils_1.defineIfNotExists)(Map.prototype, 'toObject', function () {
37
+ return (0, logic_utils_1.mapToObject)(this);
38
+ });
39
+ /**
40
+ * @see Map.prototype.ensureArray
41
+ */
42
+ (0, core_utils_1.defineIfNotExists)(Map.prototype, 'ensureArray', function (key) {
30
43
  if (key === null || key === undefined) {
31
44
  throw new TypeError('Key cannot be null or undefined');
32
45
  }
@@ -0,0 +1 @@
1
+ import '../map/map-prototype';