@geraintguan/ts-std-lib 1.0.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.
@@ -0,0 +1,474 @@
1
+ declare class HashMapMissingKeyError<TKey, TValue, TSerializedKey> extends Error {
2
+ readonly key: TKey;
3
+ readonly map: HashMap<TKey, TValue, TSerializedKey>;
4
+ constructor(map: HashMap<TKey, TValue, TSerializedKey>, key: TKey);
5
+ }
6
+ /**
7
+ * Options for creating a new map instance.
8
+ */
9
+ export interface HashMapOptions<TKey, THashedKey = TKey> {
10
+ /**
11
+ * Function called to hash a key before storing or using it to access a
12
+ * value in the map.
13
+ */
14
+ hash: (key: TKey) => THashedKey;
15
+ /**
16
+ * Optional human readable name for the map instance that is used
17
+ * for debugging purposes.
18
+ *
19
+ * @remarks
20
+ *
21
+ * Defaults to `"unknown"` if not set.
22
+ */
23
+ name?: string;
24
+ }
25
+ /**
26
+ * Function called to filter the entries in a map.
27
+ *
28
+ * @remarks
29
+ *
30
+ * It is possible to mutate the original map as you filter the entries in the
31
+ * map though this is not recommended in most cases as it is easy to introduce
32
+ * bugs in your code this way.
33
+ *
34
+ * @param value - The value of the entry in the map being filtered.
35
+ * @param key - The key of the entry in the map being filtered.
36
+ * @param index - The index of the entry in the map being filtered.
37
+ * @param original - The original map instance being filtered.
38
+ *
39
+ * @returns `true` to include the entry in the new map or `false` to exclude it.
40
+ */
41
+ export type HashMapFilterFn<TKey, TValue, THashedKey> = (value: TValue, key: THashedKey, index: number, original: HashMap<TKey, TValue, THashedKey>) => boolean;
42
+ /**
43
+ * Implementation of a key-value map that allows you to customise the way keys
44
+ * are stored by using a custom hashing function.
45
+ *
46
+ * @remarks
47
+ * Unlike an ES6 `Map` which always uses
48
+ * [SameValueZero](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness#Same-value-zero_equality)
49
+ * on the key stored as-is, map allows you to customise the way keys
50
+ * are stored by using a custom hashing function.
51
+ *
52
+ * By default this map uses {@link identity} as a hash function meaning that
53
+ * keys are stored as-is, which is the same behaviour as an ES6 `Map`.
54
+ */
55
+ export declare class HashMap<TKey, TValue, THashedKey = TKey> {
56
+ /**
57
+ * Function called to hash a key before storing or using it to access a
58
+ * value in the map.
59
+ */
60
+ readonly hash: (key: TKey) => THashedKey;
61
+ /**
62
+ * Internal data structure that we use to store the entries in the
63
+ * map.
64
+ */
65
+ protected readonly _map: Map<THashedKey, TValue>;
66
+ /**
67
+ * Human readable name for the map instance that is used for
68
+ * debugging purposes.
69
+ */
70
+ readonly name: string;
71
+ /**
72
+ * Error thrown when attempting to access a key in the map that
73
+ * does not exist.
74
+ */
75
+ static MissingKeyError: typeof HashMapMissingKeyError;
76
+ constructor(
77
+ /**
78
+ * Function called to hash a key before storing or using it to access a
79
+ * value in the map.
80
+ */
81
+ hash: (key: TKey) => THashedKey,
82
+ /**
83
+ * Internal data structure that we use to store the entries in the
84
+ * map.
85
+ */
86
+ _map?: Map<THashedKey, TValue>,
87
+ /**
88
+ * Human readable name for the map instance that is used for
89
+ * debugging purposes.
90
+ */
91
+ name?: string);
92
+ /**
93
+ * Create a new empty map instance.
94
+ *
95
+ * @remarks
96
+ *
97
+ * This function uses the {@link identity} function as the hashing function
98
+ * meaning that keys will be stored without any changes.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * const map = HashMap.empty<number, string>();
103
+ *
104
+ * [...map]; // => []
105
+ *
106
+ * map.set(1, "one");
107
+ *
108
+ * [...map]; // => [[1, "one"]]
109
+ * ```
110
+ *
111
+ * @see {@link HashMap.emptyWithCustomHash}
112
+ *
113
+ * @param options - Options to use to create the new map instance.
114
+ *
115
+ * @returns A new empty map instance.
116
+ */
117
+ static empty<TKey, TValue>(options?: Omit<HashMapOptions<TKey>, "hash">): HashMap<TKey, TValue, TKey>;
118
+ /**
119
+ * Create a new empty map instance with a custom hashing function.
120
+ *
121
+ * @param options - Options to use to create the new map instance.
122
+ *
123
+ * @returns A new empty map instance.
124
+ */
125
+ static emptyWithCustomHash<TKey, TValue, THashedKey = TKey>(options: HashMapOptions<TKey, THashedKey>): HashMap<TKey, TValue, THashedKey>;
126
+ /**
127
+ * Create a new map instance from an array of key-value pairs with
128
+ * a custom hashing function.
129
+ *
130
+ * @example Use ISO string representation of Date objects as hash keys
131
+ * ```typescript
132
+ * const map = HashMap.fromCustomEntries(
133
+ * [
134
+ * [new Date("2020-01-01"), 1],
135
+ * [new Date("2020-02-01"), 2],
136
+ * [new Date("2020-03-01"), 3],
137
+ * ],
138
+ * {
139
+ * hash(key) {
140
+ * return key.toISOString();
141
+ * },
142
+ * });
143
+ *
144
+ * [...map];
145
+ * // => [
146
+ * // ["2020-01-01T00:00:00.000Z", 1],
147
+ * // ["2020-02-01T00:00:00.000Z", 2],
148
+ * // ["2020-03-01T00:00:00.000Z", 3],
149
+ * // ];
150
+ * ```
151
+ *
152
+ * @param entries - Array of key-value pairs to create the map
153
+ * with.
154
+ * @param options - Options to use to create the new map instance.
155
+ *
156
+ * @returns A new map instance with the given key-value pairs and
157
+ * a given custom hashing function.
158
+ */
159
+ static fromCustomEntries<TKey, TValue, THashedKey>(entries: [TKey, TValue][], options: HashMapOptions<TKey, THashedKey>): HashMap<TKey, TValue, THashedKey>;
160
+ /**
161
+ * Create a new map instance from an array of key-value pairs
162
+ * using the {@link identity} as the hash function.
163
+ *
164
+ * @remarks
165
+ *
166
+ * This function uses the {@link identity} function as the hashing function
167
+ * meaning that keys will be stored without any changes which will therefore
168
+ * use the same behaviour as an ES6 `Map`.
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const map = HashMap.fromEntries<number, string>([
173
+ * [1, "one"],
174
+ * [2, "two"],
175
+ * [3, "three"],
176
+ * ]);
177
+ *
178
+ * [...map];
179
+ * // => [
180
+ * // [1, "one"],
181
+ * // [2, "two"],
182
+ * // [3, "three"],
183
+ * // ];
184
+ * ```
185
+ *
186
+ * @param entries - Array of key-value pairs to create the map
187
+ * with.
188
+ * @param options - Options to use to create the new map instance.
189
+ *
190
+ * @returns A new map instance with the given key-value pairs.
191
+ */
192
+ static fromEntries<TKey, TValue>(entries: [TKey, TValue][], options?: Omit<HashMapOptions<TKey>, "hash">): HashMap<TKey, TValue, TKey>;
193
+ /**
194
+ * Clears all of the entries in this map.
195
+ *
196
+ * @remarks
197
+ *
198
+ * This function **will mutate** the map instance it is called on.
199
+ *
200
+ * * @example
201
+ * ```typescript
202
+ * const map = HashMap.fromEntries<number, string>([
203
+ * [1, "one"],
204
+ * [2, "two"],
205
+ * [3, "three"],
206
+ * ]);
207
+ *
208
+ * map.clear();
209
+ *
210
+ * [...map]; // => []
211
+ * ```
212
+ */
213
+ clear(): void;
214
+ /**
215
+ * Delete an entry from this map by its key, throwing a
216
+ * {@link HashMap.MissingKeyError} if the key does not exist in this map.
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * const map = HashMap.fromEntries<number, string>([
221
+ * [1, "one"],
222
+ * [2, "two"],
223
+ * [3, "three"],
224
+ * ]);
225
+ *
226
+ * map.delete(2);
227
+ *
228
+ * [...map];
229
+ * // => [
230
+ * // [1, "one"],
231
+ * // [3, "three"],
232
+ * // ]
233
+ *
234
+ * map.delete(4); // throws HashMap.MissingKeyError
235
+ * ```
236
+ *
237
+ * @param key - The key of the entry to delete.
238
+ *
239
+ * @throws {@link HashMap.MissingKeyError} if the key does not exist in this
240
+ * map.
241
+ */
242
+ delete(key: TKey): void;
243
+ /**
244
+ * Delete an entry from this map by its key and returns `true` if it exists,
245
+ * otherwise it simply returns `false`.
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * const map = HashMap.fromEntries<number, string>([
250
+ * [1, "one"],
251
+ * [2, "two"],
252
+ * [3, "three"],
253
+ * ]);
254
+ *
255
+ * map.deleteIfExists(2); // => true
256
+ * map.deleteIfExists(4); // => false
257
+ *
258
+ * [...map];
259
+ * // => [
260
+ * // [1, "one"],
261
+ * // [3, "three"],
262
+ * // ]
263
+ * ```
264
+ *
265
+ * @param key - The key of the entry to delete.
266
+ *
267
+ * @returns `true` if the key existed and the entry was deleted, `false` if
268
+ * the key did not exist.
269
+ */
270
+ deleteIfExists(key: TKey): boolean;
271
+ /**
272
+ * Returns the entries in this map as an {@link IterableIterator} which each
273
+ * entry as an array of `[key, value]`.
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * const map = HashMap.fromEntries<number, string>([
278
+ * [1, "one"],
279
+ * [2, "two"],
280
+ * [3, "three"],
281
+ * ]);
282
+ *
283
+ * [...map.entries()];
284
+ * // => [
285
+ * // [1, "one"],
286
+ * // [2, "two"],
287
+ * // [3, "three"],
288
+ * // ]
289
+ * ```
290
+ *
291
+ * @returns An {@link IterableIterator} of the entries in this
292
+ * map.
293
+ */
294
+ entries(): IterableIterator<[THashedKey, TValue]>;
295
+ /**
296
+ * Returns a new map with only the key-value pairs where the given function
297
+ * returns `true`, filtering out those that the given function returns `false`
298
+ * for.
299
+ *
300
+ * @remarks
301
+ * This function does not mutate the original map instance **unless** you call
302
+ * a mutating function on the map (4th argument) inside the given function.
303
+ *
304
+ * @example Include entries where key is greater than 2
305
+ * ```typescript
306
+ * const map = HashMap.fromEntries<number, string>([
307
+ * [1, "one"],
308
+ * [2, "two"],
309
+ * [3, "three"],
310
+ * [4, "four"],
311
+ * ]);
312
+ *
313
+ * const filtered = map.filter((value, key) => key > 2);
314
+ *
315
+ * [...filtered];
316
+ * // => [
317
+ * // [3, "three"],
318
+ * // [4, "four"],
319
+ * // ]
320
+ * ```
321
+ * @example Include entries where the value has a length greater than 3
322
+ * ```typescript
323
+ * const map = HashMap.fromEntries<number, string>([
324
+ * [1, "one"],
325
+ * [2, "two"],
326
+ * [3, "three"],
327
+ * [4, "four"],
328
+ * ]);
329
+ *
330
+ * const filtered = map.filter((value) => value.length > 3);
331
+ *
332
+ * [...filtered];
333
+ * // => [
334
+ * // [3, "three"],
335
+ * // [4, "four"],
336
+ * // ]
337
+ * ```
338
+ *
339
+ * @param fn - Function called for each key-value pair in the map that returns
340
+ * `true` to include the pair in the new map or `false` to exclude it.
341
+ *
342
+ * @returns A new map with only the key-value pairs where the given function
343
+ * returned `true` for.
344
+ */
345
+ filter(fn: HashMapFilterFn<TKey, TValue, THashedKey>): HashMap<TKey, TValue, THashedKey>;
346
+ /**
347
+ * Get the value with the given key from this map, throwing a
348
+ * {@link HashMap.MissingKeyError} if the key does not exist.
349
+ *
350
+ * @example
351
+ * ```typescript
352
+ * const map = HashMap.fromEntries([
353
+ * [1, "one"],
354
+ * [2, "two"],
355
+ * [3, "three"]
356
+ * ]);
357
+ *
358
+ * map.get(2) // => "two"
359
+ *
360
+ * map.get(4) // => throws HashMap.MissingKeyError
361
+ * ```
362
+ *
363
+ * @param key - The key of the value to get.
364
+ *
365
+ * @returns The value with the given key.
366
+ */
367
+ get(key: TKey): TValue;
368
+ /**
369
+ * Get the value with the given key from this map if it exists, otherwise
370
+ * return the given default value.
371
+ *
372
+ * @param key - The key whose associated value is to be returned.
373
+ * @param defaultValue - The value to return if the key is not found.
374
+ *
375
+ * @returns - The value associated with the specified key, or the default
376
+ * value if the key does not exist.
377
+ */
378
+ getOr<TDefaultValue = TValue>(key: TKey, defaultValue: TDefaultValue): TDefaultValue | TValue;
379
+ /**
380
+ * Checks if this map has an entry with the given key.
381
+ *
382
+ * @param key - The key to check for.
383
+ *
384
+ * @returns `true` if the key exists in this map, `false` otherwise.
385
+ */
386
+ has(key: TKey): boolean;
387
+ /**
388
+ * Get the keys in this map as an {@link IterableIterator}.
389
+ *
390
+ * @returns The keys in this map as an {@link IterableIterator}.
391
+ */
392
+ keys(): IterableIterator<THashedKey>;
393
+ /**
394
+ * Create a new map with entries that are the result of calling the given
395
+ * callback function on each of the key-value pairs in this map.
396
+ *
397
+ * @example Swap the keys and values
398
+ * ```typescript
399
+ * const map = HashMap.fromEntries([
400
+ * ["one", 1],
401
+ * ["two", 2],
402
+ * ["three", 3],
403
+ * ]);
404
+ *
405
+ * const swapped = map.map(([key, value]) => [value, key]);
406
+ * // => HashMap { 1 => "one", 2 => "two", 3 => "three" }
407
+ * ```
408
+ *
409
+ * @param fn - Function to call on each key-value pair in the map. The result
410
+ * of this function is used as entries in the new map.
411
+ *
412
+ * @returns A new map with the new entries from calling the given function on
413
+ * each key-value pair in the map.
414
+ */
415
+ map(fn: (value: TValue, key: THashedKey, index: number, original: HashMap<TKey, TValue, THashedKey>) => [THashedKey, TValue]): HashMap<TKey, TValue, THashedKey>;
416
+ /**
417
+ * Create a new map with entries that have keys that are the result of calling
418
+ * the given callback function on each of the key-value pairs in this map.
419
+ *
420
+ * @remarks
421
+ *
422
+ * The new map will have the same default value as this map.
423
+ *
424
+ * This function does not mutate the original map instance **unless** you call
425
+ * a mutating function on the map (4th argument) inside the given function.
426
+ *
427
+ * @param fn - Function to call on each key-value pair in the map. The result
428
+ * of this function is used as the keys for the entries in the new map.
429
+ *
430
+ * @returns A new map with the entries with new keys from calling the given
431
+ * function on each key-value pair in the map.
432
+ */
433
+ mapKeys(fn: (key: THashedKey, value: TValue, index: number, original: HashMap<TKey, TValue, THashedKey>) => THashedKey): HashMap<TKey, TValue, THashedKey>;
434
+ /**
435
+ * Create a new map with entries that have values that are the result of
436
+ * calling the given callback function on each of the key-value pairs in this
437
+ * map.
438
+ *
439
+ * @remarks
440
+ *
441
+ * The new map will have the same default value as this map.
442
+ *
443
+ * This function does not mutate the original map instance **unless** you call
444
+ * a mutating function on the map (4th argument) inside the given function.
445
+ *
446
+ * @param fn - Function to call on each key-value pair in the map. The result
447
+ * of this function is used as the values for the entries in the new map.
448
+ *
449
+ * @returns A new map with the entries with new values from calling the given
450
+ * function on each key-value pair in the map.
451
+ */
452
+ mapValues(fn: (value: TValue, key: THashedKey, index: number, original: HashMap<TKey, TValue, THashedKey>) => TValue): HashMap<TKey, TValue, THashedKey>;
453
+ /**
454
+ * Set the value of an entry by it's key in the map, creating a new entry if
455
+ * one doesn't exist or overriding an existing entry if one does.
456
+ *
457
+ * @param key - The key of the entry to set.
458
+ * @param value - The value to set the entry to.
459
+ */
460
+ set(key: TKey, value: TValue): void;
461
+ /**
462
+ * Get the iterator over the entires in this map.
463
+ *
464
+ * @returns The entries in this map as an array of key-value pairs.
465
+ */
466
+ [Symbol.iterator](): Iterator<[THashedKey, TValue]>;
467
+ /**
468
+ * Get the values in this map as an {@link IterableIterator}.
469
+ *
470
+ * @returns The values in this map as an {@link IterableIterator}.
471
+ */
472
+ values(): IterableIterator<TValue>;
473
+ }
474
+ export {};