UNPKG

196 kBTypeScriptView Raw
1/** @ignore we should disable this rules, but let's activate it to enable eslint first */
2/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types */
3/**
4 * Immutable data encourages pure functions (data-in, data-out) and lends itself
5 * to much simpler application development and enabling techniques from
6 * functional programming such as lazy evaluation.
7 *
8 * While designed to bring these powerful functional concepts to JavaScript, it
9 * presents an Object-Oriented API familiar to Javascript engineers and closely
10 * mirroring that of Array, Map, and Set. It is easy and efficient to convert to
11 * and from plain Javascript types.
12 *
13 * ## How to read these docs
14 *
15 * In order to better explain what kinds of values the Immutable.js API expects
16 * and produces, this documentation is presented in a statically typed dialect of
17 * JavaScript (like [Flow][] or [TypeScript][]). You *don't need* to use these
18 * type checking tools in order to use Immutable.js, however becoming familiar
19 * with their syntax will help you get a deeper understanding of this API.
20 *
21 * **A few examples and how to read them.**
22 *
23 * All methods describe the kinds of data they accept and the kinds of data
24 * they return. For example a function which accepts two numbers and returns
25 * a number would look like this:
26 *
27 * ```js
28 * sum(first: number, second: number): number
29 * ```
30 *
31 * Sometimes, methods can accept different kinds of data or return different
32 * kinds of data, and this is described with a *type variable*, which is
33 * typically in all-caps. For example, a function which always returns the same
34 * kind of data it was provided would look like this:
35 *
36 * ```js
37 * identity<T>(value: T): T
38 * ```
39 *
40 * Type variables are defined with classes and referred to in methods. For
41 * example, a class that holds onto a value for you might look like this:
42 *
43 * ```js
44 * class Box<T> {
45 * constructor(value: T)
46 * getValue(): T
47 * }
48 * ```
49 *
50 * In order to manipulate Immutable data, methods that we're used to affecting
51 * a Collection instead return a new Collection of the same type. The type
52 * `this` refers to the same kind of class. For example, a List which returns
53 * new Lists when you `push` a value onto it might look like:
54 *
55 * ```js
56 * class List<T> {
57 * push(value: T): this
58 * }
59 * ```
60 *
61 * Many methods in Immutable.js accept values which implement the JavaScript
62 * [Iterable][] protocol, and might appear like `Iterable<string>` for something
63 * which represents sequence of strings. Typically in JavaScript we use plain
64 * Arrays (`[]`) when an Iterable is expected, but also all of the Immutable.js
65 * collections are iterable themselves!
66 *
67 * For example, to get a value deep within a structure of data, we might use
68 * `getIn` which expects an `Iterable` path:
69 *
70 * ```
71 * getIn(path: Iterable<string | number>): unknown
72 * ```
73 *
74 * To use this method, we could pass an array: `data.getIn([ "key", 2 ])`.
75 *
76 *
77 * Note: All examples are presented in the modern [ES2015][] version of
78 * JavaScript. Use tools like Babel to support older browsers.
79 *
80 * For example:
81 *
82 * ```js
83 * // ES2015
84 * const mappedFoo = foo.map(x => x * x);
85 * // ES5
86 * var mappedFoo = foo.map(function (x) { return x * x; });
87 * ```
88 *
89 * [ES2015]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla
90 * [TypeScript]: https://www.typescriptlang.org/
91 * [Flow]: https://flowtype.org/
92 * [Iterable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
93 */
94
95declare namespace Immutable {
96 /** @ignore */
97 type OnlyObject<T> = Extract<T, object>;
98
99 /** @ignore */
100 type ContainObject<T> = OnlyObject<T> extends object
101 ? OnlyObject<T> extends never
102 ? false
103 : true
104 : false;
105
106 /**
107 * @ignore
108 *
109 * Used to convert deeply all immutable types to a plain TS type.
110 * Using `unknown` on object instead of recursive call as we have a circular reference issue
111 */
112 export type DeepCopy<T> = T extends Record<infer R>
113 ? // convert Record to DeepCopy plain JS object
114 {
115 [key in keyof R]: ContainObject<R[key]> extends true ? unknown : R[key];
116 }
117 : T extends MapOf<infer R>
118 ? // convert MapOf to DeepCopy plain JS object
119 {
120 [key in keyof R]: ContainObject<R[key]> extends true ? unknown : R[key];
121 }
122 : T extends Collection.Keyed<infer KeyedKey, infer V>
123 ? // convert KeyedCollection to DeepCopy plain JS object
124 {
125 [key in KeyedKey extends string | number | symbol
126 ? KeyedKey
127 : string]: V extends object ? unknown : V;
128 }
129 : // convert IndexedCollection or Immutable.Set to DeepCopy plain JS array
130 // eslint-disable-next-line @typescript-eslint/no-unused-vars
131 T extends Collection<infer _, infer V>
132 ? Array<DeepCopy<V>>
133 : T extends string | number // Iterable scalar types : should be kept as is
134 ? T
135 : T extends Iterable<infer V> // Iterable are converted to plain JS array
136 ? Array<DeepCopy<V>>
137 : T extends object // plain JS object are converted deeply
138 ? {
139 [ObjectKey in keyof T]: ContainObject<T[ObjectKey]> extends true
140 ? unknown
141 : T[ObjectKey];
142 }
143 : // other case : should be kept as is
144 T;
145
146 /**
147 * Describes which item in a pair should be placed first when sorting
148 *
149 * @ignore
150 */
151 export enum PairSorting {
152 LeftThenRight = -1,
153 RightThenLeft = +1,
154 }
155
156 /**
157 * Function comparing two items of the same type. It can return:
158 *
159 * * a PairSorting value, to indicate whether the left-hand item or the right-hand item should be placed before the other
160 *
161 * * the traditional numeric return value - especially -1, 0, or 1
162 *
163 * @ignore
164 */
165 export type Comparator<T> = (left: T, right: T) => PairSorting | number;
166
167 /**
168 * Lists are ordered indexed dense collections, much like a JavaScript
169 * Array.
170 *
171 * Lists are immutable and fully persistent with O(log32 N) gets and sets,
172 * and O(1) push and pop.
173 *
174 * Lists implement Deque, with efficient addition and removal from both the
175 * end (`push`, `pop`) and beginning (`unshift`, `shift`).
176 *
177 * Unlike a JavaScript Array, there is no distinction between an
178 * "unset" index and an index set to `undefined`. `List#forEach` visits all
179 * indices from 0 to size, regardless of whether they were explicitly defined.
180 */
181 namespace List {
182 /**
183 * True if the provided value is a List
184 *
185 * <!-- runkit:activate -->
186 * ```js
187 * const { List } = require('immutable');
188 * List.isList([]); // false
189 * List.isList(List()); // true
190 * ```
191 */
192 function isList(maybeList: unknown): maybeList is List<unknown>;
193
194 /**
195 * Creates a new List containing `values`.
196 *
197 * <!-- runkit:activate -->
198 * ```js
199 * const { List } = require('immutable');
200 * List.of(1, 2, 3, 4)
201 * // List [ 1, 2, 3, 4 ]
202 * ```
203 *
204 * Note: Values are not altered or converted in any way.
205 *
206 * <!-- runkit:activate -->
207 * ```js
208 * const { List } = require('immutable');
209 * List.of({x:1}, 2, [3], 4)
210 * // List [ { x: 1 }, 2, [ 3 ], 4 ]
211 * ```
212 */
213 function of<T>(...values: Array<T>): List<T>;
214 }
215
216 /**
217 * Create a new immutable List containing the values of the provided
218 * collection-like.
219 *
220 * Note: `List` is a factory function and not a class, and does not use the
221 * `new` keyword during construction.
222 *
223 * <!-- runkit:activate -->
224 * ```js
225 * const { List, Set } = require('immutable')
226 *
227 * const emptyList = List()
228 * // List []
229 *
230 * const plainArray = [ 1, 2, 3, 4 ]
231 * const listFromPlainArray = List(plainArray)
232 * // List [ 1, 2, 3, 4 ]
233 *
234 * const plainSet = Set([ 1, 2, 3, 4 ])
235 * const listFromPlainSet = List(plainSet)
236 * // List [ 1, 2, 3, 4 ]
237 *
238 * const arrayIterator = plainArray[Symbol.iterator]()
239 * const listFromCollectionArray = List(arrayIterator)
240 * // List [ 1, 2, 3, 4 ]
241 *
242 * listFromPlainArray.equals(listFromCollectionArray) // true
243 * listFromPlainSet.equals(listFromCollectionArray) // true
244 * listFromPlainSet.equals(listFromPlainArray) // true
245 * ```
246 */
247 function List<T>(collection?: Iterable<T> | ArrayLike<T>): List<T>;
248
249 interface List<T> extends Collection.Indexed<T> {
250 /**
251 * The number of items in this List.
252 */
253 readonly size: number;
254
255 // Persistent changes
256
257 /**
258 * Returns a new List which includes `value` at `index`. If `index` already
259 * exists in this List, it will be replaced.
260 *
261 * `index` may be a negative number, which indexes back from the end of the
262 * List. `v.set(-1, "value")` sets the last item in the List.
263 *
264 * If `index` larger than `size`, the returned List's `size` will be large
265 * enough to include the `index`.
266 *
267 * <!-- runkit:activate
268 * { "preamble": "const { List } = require('immutable');" }
269 * -->
270 * ```js
271 * const originalList = List([ 0 ]);
272 * // List [ 0 ]
273 * originalList.set(1, 1);
274 * // List [ 0, 1 ]
275 * originalList.set(0, 'overwritten');
276 * // List [ "overwritten" ]
277 * originalList.set(2, 2);
278 * // List [ 0, undefined, 2 ]
279 *
280 * List().set(50000, 'value').size;
281 * // 50001
282 * ```
283 *
284 * Note: `set` can be used in `withMutations`.
285 */
286 set(index: number, value: T): List<T>;
287
288 /**
289 * Returns a new List which excludes this `index` and with a size 1 less
290 * than this List. Values at indices above `index` are shifted down by 1 to
291 * fill the position.
292 *
293 * This is synonymous with `list.splice(index, 1)`.
294 *
295 * `index` may be a negative number, which indexes back from the end of the
296 * List. `v.delete(-1)` deletes the last item in the List.
297 *
298 * Note: `delete` cannot be safely used in IE8
299 *
300 * <!-- runkit:activate
301 * { "preamble": "const { List } = require('immutable');" }
302 * -->
303 * ```js
304 * List([ 0, 1, 2, 3, 4 ]).delete(0);
305 * // List [ 1, 2, 3, 4 ]
306 * ```
307 *
308 * Since `delete()` re-indexes values, it produces a complete copy, which
309 * has `O(N)` complexity.
310 *
311 * Note: `delete` *cannot* be used in `withMutations`.
312 *
313 * @alias remove
314 */
315 delete(index: number): List<T>;
316 remove(index: number): List<T>;
317
318 /**
319 * Returns a new List with `value` at `index` with a size 1 more than this
320 * List. Values at indices above `index` are shifted over by 1.
321 *
322 * This is synonymous with `list.splice(index, 0, value)`.
323 *
324 * <!-- runkit:activate
325 * { "preamble": "const { List } = require('immutable');" }
326 * -->
327 * ```js
328 * List([ 0, 1, 2, 3, 4 ]).insert(6, 5)
329 * // List [ 0, 1, 2, 3, 4, 5 ]
330 * ```
331 *
332 * Since `insert()` re-indexes values, it produces a complete copy, which
333 * has `O(N)` complexity.
334 *
335 * Note: `insert` *cannot* be used in `withMutations`.
336 */
337 insert(index: number, value: T): List<T>;
338
339 /**
340 * Returns a new List with 0 size and no values in constant time.
341 *
342 * <!-- runkit:activate
343 * { "preamble": "const { List } = require('immutable');" }
344 * -->
345 * ```js
346 * List([ 1, 2, 3, 4 ]).clear()
347 * // List []
348 * ```
349 *
350 * Note: `clear` can be used in `withMutations`.
351 */
352 clear(): List<T>;
353
354 /**
355 * Returns a new List with the provided `values` appended, starting at this
356 * List's `size`.
357 *
358 * <!-- runkit:activate
359 * { "preamble": "const { List } = require('immutable');" }
360 * -->
361 * ```js
362 * List([ 1, 2, 3, 4 ]).push(5)
363 * // List [ 1, 2, 3, 4, 5 ]
364 * ```
365 *
366 * Note: `push` can be used in `withMutations`.
367 */
368 push(...values: Array<T>): List<T>;
369
370 /**
371 * Returns a new List with a size ones less than this List, excluding
372 * the last index in this List.
373 *
374 * Note: this differs from `Array#pop` because it returns a new
375 * List rather than the removed value. Use `last()` to get the last value
376 * in this List.
377 *
378 * ```js
379 * List([ 1, 2, 3, 4 ]).pop()
380 * // List[ 1, 2, 3 ]
381 * ```
382 *
383 * Note: `pop` can be used in `withMutations`.
384 */
385 pop(): List<T>;
386
387 /**
388 * Returns a new List with the provided `values` prepended, shifting other
389 * values ahead to higher indices.
390 *
391 * <!-- runkit:activate
392 * { "preamble": "const { List } = require('immutable');" }
393 * -->
394 * ```js
395 * List([ 2, 3, 4]).unshift(1);
396 * // List [ 1, 2, 3, 4 ]
397 * ```
398 *
399 * Note: `unshift` can be used in `withMutations`.
400 */
401 unshift(...values: Array<T>): List<T>;
402
403 /**
404 * Returns a new List with a size ones less than this List, excluding
405 * the first index in this List, shifting all other values to a lower index.
406 *
407 * Note: this differs from `Array#shift` because it returns a new
408 * List rather than the removed value. Use `first()` to get the first
409 * value in this List.
410 *
411 * <!-- runkit:activate
412 * { "preamble": "const { List } = require('immutable');" }
413 * -->
414 * ```js
415 * List([ 0, 1, 2, 3, 4 ]).shift();
416 * // List [ 1, 2, 3, 4 ]
417 * ```
418 *
419 * Note: `shift` can be used in `withMutations`.
420 */
421 shift(): List<T>;
422
423 /**
424 * Returns a new List with an updated value at `index` with the return
425 * value of calling `updater` with the existing value, or `notSetValue` if
426 * `index` was not set. If called with a single argument, `updater` is
427 * called with the List itself.
428 *
429 * `index` may be a negative number, which indexes back from the end of the
430 * List. `v.update(-1)` updates the last item in the List.
431 *
432 * <!-- runkit:activate
433 * { "preamble": "const { List } = require('immutable');" }
434 * -->
435 * ```js
436 * const list = List([ 'a', 'b', 'c' ])
437 * const result = list.update(2, val => val.toUpperCase())
438 * // List [ "a", "b", "C" ]
439 * ```
440 *
441 * This can be very useful as a way to "chain" a normal function into a
442 * sequence of methods. RxJS calls this "let" and lodash calls it "thru".
443 *
444 * For example, to sum a List after mapping and filtering:
445 *
446 * <!-- runkit:activate
447 * { "preamble": "const { List } = require('immutable');" }
448 * -->
449 * ```js
450 * function sum(collection) {
451 * return collection.reduce((sum, x) => sum + x, 0)
452 * }
453 *
454 * List([ 1, 2, 3 ])
455 * .map(x => x + 1)
456 * .filter(x => x % 2 === 0)
457 * .update(sum)
458 * // 6
459 * ```
460 *
461 * Note: `update(index)` can be used in `withMutations`.
462 *
463 * @see `Map#update`
464 */
465 update(index: number, notSetValue: T, updater: (value: T) => T): this;
466 update(
467 index: number,
468 updater: (value: T | undefined) => T | undefined
469 ): this;
470 update<R>(updater: (value: this) => R): R;
471
472 /**
473 * Returns a new List with size `size`. If `size` is less than this
474 * List's size, the new List will exclude values at the higher indices.
475 * If `size` is greater than this List's size, the new List will have
476 * undefined values for the newly available indices.
477 *
478 * When building a new List and the final size is known up front, `setSize`
479 * used in conjunction with `withMutations` may result in the more
480 * performant construction.
481 */
482 setSize(size: number): List<T>;
483
484 // Deep persistent changes
485
486 /**
487 * Returns a new List having set `value` at this `keyPath`. If any keys in
488 * `keyPath` do not exist, a new immutable Map will be created at that key.
489 *
490 * Index numbers are used as keys to determine the path to follow in
491 * the List.
492 *
493 * <!-- runkit:activate -->
494 * ```js
495 * const { List } = require('immutable')
496 * const list = List([ 0, 1, 2, List([ 3, 4 ])])
497 * list.setIn([3, 0], 999);
498 * // List [ 0, 1, 2, List [ 999, 4 ] ]
499 * ```
500 *
501 * Plain JavaScript Object or Arrays may be nested within an Immutable.js
502 * Collection, and setIn() can update those values as well, treating them
503 * immutably by creating new copies of those values with the changes applied.
504 *
505 * <!-- runkit:activate -->
506 * ```js
507 * const { List } = require('immutable')
508 * const list = List([ 0, 1, 2, { plain: 'object' }])
509 * list.setIn([3, 'plain'], 'value');
510 * // List([ 0, 1, 2, { plain: 'value' }])
511 * ```
512 *
513 * Note: `setIn` can be used in `withMutations`.
514 */
515 setIn(keyPath: Iterable<unknown>, value: unknown): this;
516
517 /**
518 * Returns a new List having removed the value at this `keyPath`. If any
519 * keys in `keyPath` do not exist, no change will occur.
520 *
521 * <!-- runkit:activate -->
522 * ```js
523 * const { List } = require('immutable')
524 * const list = List([ 0, 1, 2, List([ 3, 4 ])])
525 * list.deleteIn([3, 0]);
526 * // List [ 0, 1, 2, List [ 4 ] ]
527 * ```
528 *
529 * Plain JavaScript Object or Arrays may be nested within an Immutable.js
530 * Collection, and removeIn() can update those values as well, treating them
531 * immutably by creating new copies of those values with the changes applied.
532 *
533 * <!-- runkit:activate -->
534 * ```js
535 * const { List } = require('immutable')
536 * const list = List([ 0, 1, 2, { plain: 'object' }])
537 * list.removeIn([3, 'plain']);
538 * // List([ 0, 1, 2, {}])
539 * ```
540 *
541 * Note: `deleteIn` *cannot* be safely used in `withMutations`.
542 *
543 * @alias removeIn
544 */
545 deleteIn(keyPath: Iterable<unknown>): this;
546 removeIn(keyPath: Iterable<unknown>): this;
547
548 /**
549 * Note: `updateIn` can be used in `withMutations`.
550 *
551 * @see `Map#updateIn`
552 */
553 updateIn(
554 keyPath: Iterable<unknown>,
555 notSetValue: unknown,
556 updater: (value: unknown) => unknown
557 ): this;
558 updateIn(
559 keyPath: Iterable<unknown>,
560 updater: (value: unknown) => unknown
561 ): this;
562
563 /**
564 * Note: `mergeIn` can be used in `withMutations`.
565 *
566 * @see `Map#mergeIn`
567 */
568 mergeIn(keyPath: Iterable<unknown>, ...collections: Array<unknown>): this;
569
570 /**
571 * Note: `mergeDeepIn` can be used in `withMutations`.
572 *
573 * @see `Map#mergeDeepIn`
574 */
575 mergeDeepIn(
576 keyPath: Iterable<unknown>,
577 ...collections: Array<unknown>
578 ): this;
579
580 // Transient changes
581
582 /**
583 * Note: Not all methods can be safely used on a mutable collection or within
584 * `withMutations`! Check the documentation for each method to see if it
585 * allows being used in `withMutations`.
586 *
587 * @see `Map#withMutations`
588 */
589 withMutations(mutator: (mutable: this) => unknown): this;
590
591 /**
592 * An alternative API for withMutations()
593 *
594 * Note: Not all methods can be safely used on a mutable collection or within
595 * `withMutations`! Check the documentation for each method to see if it
596 * allows being used in `withMutations`.
597 *
598 * @see `Map#asMutable`
599 */
600 asMutable(): this;
601
602 /**
603 * @see `Map#wasAltered`
604 */
605 wasAltered(): boolean;
606
607 /**
608 * @see `Map#asImmutable`
609 */
610 asImmutable(): this;
611
612 // Sequence algorithms
613
614 /**
615 * Returns a new List with other values or collections concatenated to this one.
616 *
617 * Note: `concat` can be used in `withMutations`.
618 *
619 * @alias merge
620 */
621 concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): List<T | C>;
622 merge<C>(...collections: Array<Iterable<C>>): List<T | C>;
623
624 /**
625 * Returns a new List with values passed through a
626 * `mapper` function.
627 *
628 * <!-- runkit:activate
629 * { "preamble": "const { List } = require('immutable');" }
630 * -->
631 * ```js
632 * List([ 1, 2 ]).map(x => 10 * x)
633 * // List [ 10, 20 ]
634 * ```
635 */
636 map<M>(
637 mapper: (value: T, key: number, iter: this) => M,
638 context?: unknown
639 ): List<M>;
640
641 /**
642 * Flat-maps the List, returning a new List.
643 *
644 * Similar to `list.map(...).flatten(true)`.
645 */
646 flatMap<M>(
647 mapper: (value: T, key: number, iter: this) => Iterable<M>,
648 context?: unknown
649 ): List<M>;
650
651 /**
652 * Returns a new List with only the values for which the `predicate`
653 * function returns true.
654 *
655 * Note: `filter()` always returns a new instance, even if it results in
656 * not filtering out any values.
657 */
658 filter<F extends T>(
659 predicate: (value: T, index: number, iter: this) => value is F,
660 context?: unknown
661 ): List<F>;
662 filter(
663 predicate: (value: T, index: number, iter: this) => unknown,
664 context?: unknown
665 ): this;
666
667 /**
668 * Returns a new List with the values for which the `predicate`
669 * function returns false and another for which is returns true.
670 */
671 partition<F extends T, C>(
672 predicate: (this: C, value: T, index: number, iter: this) => value is F,
673 context?: C
674 ): [List<T>, List<F>];
675 partition<C>(
676 predicate: (this: C, value: T, index: number, iter: this) => unknown,
677 context?: C
678 ): [this, this];
679
680 /**
681 * Returns a List "zipped" with the provided collection.
682 *
683 * Like `zipWith`, but using the default `zipper`: creating an `Array`.
684 *
685 * <!-- runkit:activate
686 * { "preamble": "const { List } = require('immutable');" }
687 * -->
688 * ```js
689 * const a = List([ 1, 2, 3 ]);
690 * const b = List([ 4, 5, 6 ]);
691 * const c = a.zip(b); // List [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
692 * ```
693 */
694 zip<U>(other: Collection<unknown, U>): List<[T, U]>;
695 zip<U, V>(
696 other: Collection<unknown, U>,
697 other2: Collection<unknown, V>
698 ): List<[T, U, V]>;
699 zip(...collections: Array<Collection<unknown, unknown>>): List<unknown>;
700
701 /**
702 * Returns a List "zipped" with the provided collections.
703 *
704 * Unlike `zip`, `zipAll` continues zipping until the longest collection is
705 * exhausted. Missing values from shorter collections are filled with `undefined`.
706 *
707 * <!-- runkit:activate
708 * { "preamble": "const { List } = require('immutable');" }
709 * -->
710 * ```js
711 * const a = List([ 1, 2 ]);
712 * const b = List([ 3, 4, 5 ]);
713 * const c = a.zipAll(b); // List [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ]
714 * ```
715 *
716 * Note: Since zipAll will return a collection as large as the largest
717 * input, some results may contain undefined values. TypeScript cannot
718 * account for these without cases (as of v2.5).
719 */
720 zipAll<U>(other: Collection<unknown, U>): List<[T, U]>;
721 zipAll<U, V>(
722 other: Collection<unknown, U>,
723 other2: Collection<unknown, V>
724 ): List<[T, U, V]>;
725 zipAll(...collections: Array<Collection<unknown, unknown>>): List<unknown>;
726
727 /**
728 * Returns a List "zipped" with the provided collections by using a
729 * custom `zipper` function.
730 *
731 * <!-- runkit:activate
732 * { "preamble": "const { List } = require('immutable');" }
733 * -->
734 * ```js
735 * const a = List([ 1, 2, 3 ]);
736 * const b = List([ 4, 5, 6 ]);
737 * const c = a.zipWith((a, b) => a + b, b);
738 * // List [ 5, 7, 9 ]
739 * ```
740 */
741 zipWith<U, Z>(
742 zipper: (value: T, otherValue: U) => Z,
743 otherCollection: Collection<unknown, U>
744 ): List<Z>;
745 zipWith<U, V, Z>(
746 zipper: (value: T, otherValue: U, thirdValue: V) => Z,
747 otherCollection: Collection<unknown, U>,
748 thirdCollection: Collection<unknown, V>
749 ): List<Z>;
750 zipWith<Z>(
751 zipper: (...values: Array<unknown>) => Z,
752 ...collections: Array<Collection<unknown, unknown>>
753 ): List<Z>;
754 }
755
756 /**
757 * Immutable Map is an unordered Collection.Keyed of (key, value) pairs with
758 * `O(log32 N)` gets and `O(log32 N)` persistent sets.
759 *
760 * Iteration order of a Map is undefined, however is stable. Multiple
761 * iterations of the same Map will iterate in the same order.
762 *
763 * Map's keys can be of any type, and use `Immutable.is` to determine key
764 * equality. This allows the use of any value (including NaN) as a key.
765 *
766 * Because `Immutable.is` returns equality based on value semantics, and
767 * Immutable collections are treated as values, any Immutable collection may
768 * be used as a key.
769 *
770 * <!-- runkit:activate -->
771 * ```js
772 * const { Map, List } = require('immutable');
773 * Map().set(List([ 1 ]), 'listofone').get(List([ 1 ]));
774 * // 'listofone'
775 * ```
776 *
777 * Any JavaScript object may be used as a key, however strict identity is used
778 * to evaluate key equality. Two similar looking objects will represent two
779 * different keys.
780 *
781 * Implemented by a hash-array mapped trie.
782 */
783 namespace Map {
784 /**
785 * True if the provided value is a Map
786 *
787 * <!-- runkit:activate -->
788 * ```js
789 * const { Map } = require('immutable')
790 * Map.isMap({}) // false
791 * Map.isMap(Map()) // true
792 * ```
793 */
794 function isMap(maybeMap: unknown): maybeMap is Map<unknown, unknown>;
795 }
796
797 /**
798 * Creates a new Immutable Map.
799 *
800 * Created with the same key value pairs as the provided Collection.Keyed or
801 * JavaScript Object or expects a Collection of [K, V] tuple entries.
802 *
803 * Note: `Map` is a factory function and not a class, and does not use the
804 * `new` keyword during construction.
805 *
806 * <!-- runkit:activate -->
807 * ```js
808 * const { Map } = require('immutable')
809 * Map({ key: "value" })
810 * Map([ [ "key", "value" ] ])
811 * ```
812 *
813 * Keep in mind, when using JS objects to construct Immutable Maps, that
814 * JavaScript Object properties are always strings, even if written in a
815 * quote-less shorthand, while Immutable Maps accept keys of any type.
816 *
817 * <!-- runkit:activate
818 * { "preamble": "const { Map } = require('immutable');" }
819 * -->
820 * ```js
821 * let obj = { 1: "one" }
822 * Object.keys(obj) // [ "1" ]
823 * assert.equal(obj["1"], obj[1]) // "one" === "one"
824 *
825 * let map = Map(obj)
826 * assert.notEqual(map.get("1"), map.get(1)) // "one" !== undefined
827 * ```
828 *
829 * Property access for JavaScript Objects first converts the key to a string,
830 * but since Immutable Map keys can be of any type the argument to `get()` is
831 * not altered.
832 */
833 function Map<K, V>(collection?: Iterable<[K, V]>): Map<K, V>;
834 function Map<R extends { [key in string | number | symbol]: unknown }>(
835 obj: R
836 ): MapOf<R>;
837 function Map<V>(obj: { [key: string]: V }): Map<string, V>;
838 function Map<K extends string | symbol, V>(obj: { [P in K]?: V }): Map<K, V>;
839
840 /**
841 * Represent a Map constructed by an object
842 *
843 * @ignore
844 */
845 interface MapOf<R extends { [key in string | number | symbol]: unknown }>
846 extends Map<keyof R, R[keyof R]> {
847 /**
848 * Returns the value associated with the provided key, or notSetValue if
849 * the Collection does not contain this key.
850 *
851 * Note: it is possible a key may be associated with an `undefined` value,
852 * so if `notSetValue` is not provided and this method returns `undefined`,
853 * that does not guarantee the key was not found.
854 */
855 get<K extends keyof R>(key: K, notSetValue?: unknown): R[K];
856 get<NSV>(key: any, notSetValue: NSV): NSV;
857
858 // TODO `<const P extends ...>` can be used after dropping support for TypeScript 4.x
859 // reference: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#const-type-parameters
860 // after this change, `as const` assertions can be remove from the type tests
861 getIn<P extends ReadonlyArray<string | number | symbol>>(
862 searchKeyPath: [...P],
863 notSetValue?: unknown
864 ): RetrievePath<R, P>;
865
866 set<K extends keyof R>(key: K, value: R[K]): this;
867
868 update(updater: (value: this) => this): this;
869 update<K extends keyof R>(key: K, updater: (value: R[K]) => R[K]): this;
870 update<K extends keyof R, NSV extends R[K]>(
871 key: K,
872 notSetValue: NSV,
873 updater: (value: R[K]) => R[K]
874 ): this;
875
876 // Possible best type is MapOf<Omit<R, K>> but Omit seems to broke other function calls
877 // and generate recursion error with other methods (update, merge, etc.) until those functions are defined in MapOf
878 delete<K extends keyof R>(
879 key: K
880 ): Extract<R[K], undefined> extends never ? never : this;
881 remove<K extends keyof R>(
882 key: K
883 ): Extract<R[K], undefined> extends never ? never : this;
884
885 toJS(): { [K in keyof R]: DeepCopy<R[K]> };
886
887 toJSON(): { [K in keyof R]: R[K] };
888 }
889
890 // Loosely based off of this work.
891 // https://github.com/immutable-js/immutable-js/issues/1462#issuecomment-584123268
892
893 /** @ignore */
894 type GetMapType<S> = S extends MapOf<infer T> ? T : S;
895
896 /** @ignore */
897 type Head<T extends ReadonlyArray<any>> = T extends [
898 infer H,
899 ...Array<unknown>
900 ]
901 ? H
902 : never;
903
904 /** @ignore */
905 type Tail<T extends ReadonlyArray<any>> = T extends [unknown, ...infer I]
906 ? I
907 : Array<never>;
908
909 /** @ignore */
910 type RetrievePathReducer<
911 T,
912 C,
913 L extends ReadonlyArray<any>
914 > = C extends keyof GetMapType<T>
915 ? L extends []
916 ? GetMapType<T>[C]
917 : RetrievePathReducer<GetMapType<T>[C], Head<L>, Tail<L>>
918 : never;
919
920 /** @ignore */
921 type RetrievePath<
922 R,
923 P extends ReadonlyArray<string | number | symbol>
924 > = P extends [] ? P : RetrievePathReducer<R, Head<P>, Tail<P>>;
925
926 interface Map<K, V> extends Collection.Keyed<K, V> {
927 /**
928 * The number of entries in this Map.
929 */
930 readonly size: number;
931
932 // Persistent changes
933
934 /**
935 * Returns a new Map also containing the new key, value pair. If an equivalent
936 * key already exists in this Map, it will be replaced.
937 *
938 * <!-- runkit:activate -->
939 * ```js
940 * const { Map } = require('immutable')
941 * const originalMap = Map()
942 * const newerMap = originalMap.set('key', 'value')
943 * const newestMap = newerMap.set('key', 'newer value')
944 *
945 * originalMap
946 * // Map {}
947 * newerMap
948 * // Map { "key": "value" }
949 * newestMap
950 * // Map { "key": "newer value" }
951 * ```
952 *
953 * Note: `set` can be used in `withMutations`.
954 */
955 set(key: K, value: V): this;
956
957 /**
958 * Returns a new Map which excludes this `key`.
959 *
960 * Note: `delete` cannot be safely used in IE8, but is provided to mirror
961 * the ES6 collection API.
962 *
963 * <!-- runkit:activate -->
964 * ```js
965 * const { Map } = require('immutable')
966 * const originalMap = Map({
967 * key: 'value',
968 * otherKey: 'other value'
969 * })
970 * // Map { "key": "value", "otherKey": "other value" }
971 * originalMap.delete('otherKey')
972 * // Map { "key": "value" }
973 * ```
974 *
975 * Note: `delete` can be used in `withMutations`.
976 *
977 * @alias remove
978 */
979 delete(key: K): this;
980 remove(key: K): this;
981
982 /**
983 * Returns a new Map which excludes the provided `keys`.
984 *
985 * <!-- runkit:activate -->
986 * ```js
987 * const { Map } = require('immutable')
988 * const names = Map({ a: "Aaron", b: "Barry", c: "Connor" })
989 * names.deleteAll([ 'a', 'c' ])
990 * // Map { "b": "Barry" }
991 * ```
992 *
993 * Note: `deleteAll` can be used in `withMutations`.
994 *
995 * @alias removeAll
996 */
997 deleteAll(keys: Iterable<K>): this;
998 removeAll(keys: Iterable<K>): this;
999
1000 /**
1001 * Returns a new Map containing no keys or values.
1002 *
1003 * <!-- runkit:activate -->
1004 * ```js
1005 * const { Map } = require('immutable')
1006 * Map({ key: 'value' }).clear()
1007 * // Map {}
1008 * ```
1009 *
1010 * Note: `clear` can be used in `withMutations`.
1011 */
1012 clear(): this;
1013
1014 /**
1015 * Returns a new Map having updated the value at this `key` with the return
1016 * value of calling `updater` with the existing value.
1017 *
1018 * Similar to: `map.set(key, updater(map.get(key)))`.
1019 *
1020 * <!-- runkit:activate -->
1021 * ```js
1022 * const { Map } = require('immutable')
1023 * const aMap = Map({ key: 'value' })
1024 * const newMap = aMap.update('key', value => value + value)
1025 * // Map { "key": "valuevalue" }
1026 * ```
1027 *
1028 * This is most commonly used to call methods on collections within a
1029 * structure of data. For example, in order to `.push()` onto a nested `List`,
1030 * `update` and `push` can be used together:
1031 *
1032 * <!-- runkit:activate
1033 * { "preamble": "const { Map, List } = require('immutable');" }
1034 * -->
1035 * ```js
1036 * const aMap = Map({ nestedList: List([ 1, 2, 3 ]) })
1037 * const newMap = aMap.update('nestedList', list => list.push(4))
1038 * // Map { "nestedList": List [ 1, 2, 3, 4 ] }
1039 * ```
1040 *
1041 * When a `notSetValue` is provided, it is provided to the `updater`
1042 * function when the value at the key does not exist in the Map.
1043 *
1044 * <!-- runkit:activate
1045 * { "preamble": "const { Map } = require('immutable');" }
1046 * -->
1047 * ```js
1048 * const aMap = Map({ key: 'value' })
1049 * const newMap = aMap.update('noKey', 'no value', value => value + value)
1050 * // Map { "key": "value", "noKey": "no valueno value" }
1051 * ```
1052 *
1053 * However, if the `updater` function returns the same value it was called
1054 * with, then no change will occur. This is still true if `notSetValue`
1055 * is provided.
1056 *
1057 * <!-- runkit:activate
1058 * { "preamble": "const { Map } = require('immutable');" }
1059 * -->
1060 * ```js
1061 * const aMap = Map({ apples: 10 })
1062 * const newMap = aMap.update('oranges', 0, val => val)
1063 * // Map { "apples": 10 }
1064 * assert.strictEqual(newMap, map);
1065 * ```
1066 *
1067 * For code using ES2015 or later, using `notSetValue` is discourged in
1068 * favor of function parameter default values. This helps to avoid any
1069 * potential confusion with identify functions as described above.
1070 *
1071 * The previous example behaves differently when written with default values:
1072 *
1073 * <!-- runkit:activate
1074 * { "preamble": "const { Map } = require('immutable');" }
1075 * -->
1076 * ```js
1077 * const aMap = Map({ apples: 10 })
1078 * const newMap = aMap.update('oranges', (val = 0) => val)
1079 * // Map { "apples": 10, "oranges": 0 }
1080 * ```
1081 *
1082 * If no key is provided, then the `updater` function return value is
1083 * returned as well.
1084 *
1085 * <!-- runkit:activate
1086 * { "preamble": "const { Map } = require('immutable');" }
1087 * -->
1088 * ```js
1089 * const aMap = Map({ key: 'value' })
1090 * const result = aMap.update(aMap => aMap.get('key'))
1091 * // "value"
1092 * ```
1093 *
1094 * This can be very useful as a way to "chain" a normal function into a
1095 * sequence of methods. RxJS calls this "let" and lodash calls it "thru".
1096 *
1097 * For example, to sum the values in a Map
1098 *
1099 * <!-- runkit:activate
1100 * { "preamble": "const { Map } = require('immutable');" }
1101 * -->
1102 * ```js
1103 * function sum(collection) {
1104 * return collection.reduce((sum, x) => sum + x, 0)
1105 * }
1106 *
1107 * Map({ x: 1, y: 2, z: 3 })
1108 * .map(x => x + 1)
1109 * .filter(x => x % 2 === 0)
1110 * .update(sum)
1111 * // 6
1112 * ```
1113 *
1114 * Note: `update(key)` can be used in `withMutations`.
1115 */
1116 update(key: K, notSetValue: V, updater: (value: V) => V): this;
1117 update(key: K, updater: (value: V | undefined) => V | undefined): this;
1118 update<R>(updater: (value: this) => R): R;
1119
1120 /**
1121 * Returns a new Map resulting from merging the provided Collections
1122 * (or JS objects) into this Map. In other words, this takes each entry of
1123 * each collection and sets it on this Map.
1124 *
1125 * Note: Values provided to `merge` are shallowly converted before being
1126 * merged. No nested values are altered.
1127 *
1128 * <!-- runkit:activate -->
1129 * ```js
1130 * const { Map } = require('immutable')
1131 * const one = Map({ a: 10, b: 20, c: 30 })
1132 * const two = Map({ b: 40, a: 50, d: 60 })
1133 * one.merge(two) // Map { "a": 50, "b": 40, "c": 30, "d": 60 }
1134 * two.merge(one) // Map { "b": 20, "a": 10, "d": 60, "c": 30 }
1135 * ```
1136 *
1137 * Note: `merge` can be used in `withMutations`.
1138 *
1139 * @alias concat
1140 */
1141 merge<KC, VC>(
1142 ...collections: Array<Iterable<[KC, VC]>>
1143 ): Map<K | KC, Exclude<V, VC> | VC>;
1144 merge<C>(
1145 ...collections: Array<{ [key: string]: C }>
1146 ): Map<K | string, Exclude<V, C> | C>;
1147
1148 concat<KC, VC>(
1149 ...collections: Array<Iterable<[KC, VC]>>
1150 ): Map<K | KC, Exclude<V, VC> | VC>;
1151 concat<C>(
1152 ...collections: Array<{ [key: string]: C }>
1153 ): Map<K | string, Exclude<V, C> | C>;
1154
1155 /**
1156 * Like `merge()`, `mergeWith()` returns a new Map resulting from merging
1157 * the provided Collections (or JS objects) into this Map, but uses the
1158 * `merger` function for dealing with conflicts.
1159 *
1160 * <!-- runkit:activate -->
1161 * ```js
1162 * const { Map } = require('immutable')
1163 * const one = Map({ a: 10, b: 20, c: 30 })
1164 * const two = Map({ b: 40, a: 50, d: 60 })
1165 * one.mergeWith((oldVal, newVal) => oldVal / newVal, two)
1166 * // { "a": 0.2, "b": 0.5, "c": 30, "d": 60 }
1167 * two.mergeWith((oldVal, newVal) => oldVal / newVal, one)
1168 * // { "b": 2, "a": 5, "d": 60, "c": 30 }
1169 * ```
1170 *
1171 * Note: `mergeWith` can be used in `withMutations`.
1172 */
1173 mergeWith<KC, VC, VCC>(
1174 merger: (oldVal: V, newVal: VC, key: K) => VCC,
1175 ...collections: Array<Iterable<[KC, VC]>>
1176 ): Map<K | KC, V | VC | VCC>;
1177 mergeWith<C, CC>(
1178 merger: (oldVal: V, newVal: C, key: string) => CC,
1179 ...collections: Array<{ [key: string]: C }>
1180 ): Map<K | string, V | C | CC>;
1181
1182 /**
1183 * Like `merge()`, but when two compatible collections are encountered with
1184 * the same key, it merges them as well, recursing deeply through the nested
1185 * data. Two collections are considered to be compatible (and thus will be
1186 * merged together) if they both fall into one of three categories: keyed
1187 * (e.g., `Map`s, `Record`s, and objects), indexed (e.g., `List`s and
1188 * arrays), or set-like (e.g., `Set`s). If they fall into separate
1189 * categories, `mergeDeep` will replace the existing collection with the
1190 * collection being merged in. This behavior can be customized by using
1191 * `mergeDeepWith()`.
1192 *
1193 * Note: Indexed and set-like collections are merged using
1194 * `concat()`/`union()` and therefore do not recurse.
1195 *
1196 * <!-- runkit:activate -->
1197 * ```js
1198 * const { Map } = require('immutable')
1199 * const one = Map({ a: Map({ x: 10, y: 10 }), b: Map({ x: 20, y: 50 }) })
1200 * const two = Map({ a: Map({ x: 2 }), b: Map({ y: 5 }), c: Map({ z: 3 }) })
1201 * one.mergeDeep(two)
1202 * // Map {
1203 * // "a": Map { "x": 2, "y": 10 },
1204 * // "b": Map { "x": 20, "y": 5 },
1205 * // "c": Map { "z": 3 }
1206 * // }
1207 * ```
1208 *
1209 * Note: `mergeDeep` can be used in `withMutations`.
1210 */
1211 mergeDeep<KC, VC>(
1212 ...collections: Array<Iterable<[KC, VC]>>
1213 ): Map<K | KC, V | VC>;
1214 mergeDeep<C>(
1215 ...collections: Array<{ [key: string]: C }>
1216 ): Map<K | string, V | C>;
1217
1218 /**
1219 * Like `mergeDeep()`, but when two non-collections or incompatible
1220 * collections are encountered at the same key, it uses the `merger`
1221 * function to determine the resulting value. Collections are considered
1222 * incompatible if they fall into separate categories between keyed,
1223 * indexed, and set-like.
1224 *
1225 * <!-- runkit:activate -->
1226 * ```js
1227 * const { Map } = require('immutable')
1228 * const one = Map({ a: Map({ x: 10, y: 10 }), b: Map({ x: 20, y: 50 }) })
1229 * const two = Map({ a: Map({ x: 2 }), b: Map({ y: 5 }), c: Map({ z: 3 }) })
1230 * one.mergeDeepWith((oldVal, newVal) => oldVal / newVal, two)
1231 * // Map {
1232 * // "a": Map { "x": 5, "y": 10 },
1233 * // "b": Map { "x": 20, "y": 10 },
1234 * // "c": Map { "z": 3 }
1235 * // }
1236 * ```
1237 *
1238 * Note: `mergeDeepWith` can be used in `withMutations`.
1239 */
1240 mergeDeepWith(
1241 merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown,
1242 ...collections: Array<Iterable<[K, V]> | { [key: string]: V }>
1243 ): this;
1244
1245 // Deep persistent changes
1246
1247 /**
1248 * Returns a new Map having set `value` at this `keyPath`. If any keys in
1249 * `keyPath` do not exist, a new immutable Map will be created at that key.
1250 *
1251 * <!-- runkit:activate -->
1252 * ```js
1253 * const { Map } = require('immutable')
1254 * const originalMap = Map({
1255 * subObject: Map({
1256 * subKey: 'subvalue',
1257 * subSubObject: Map({
1258 * subSubKey: 'subSubValue'
1259 * })
1260 * })
1261 * })
1262 *
1263 * const newMap = originalMap.setIn(['subObject', 'subKey'], 'ha ha!')
1264 * // Map {
1265 * // "subObject": Map {
1266 * // "subKey": "ha ha!",
1267 * // "subSubObject": Map { "subSubKey": "subSubValue" }
1268 * // }
1269 * // }
1270 *
1271 * const newerMap = originalMap.setIn(
1272 * ['subObject', 'subSubObject', 'subSubKey'],
1273 * 'ha ha ha!'
1274 * )
1275 * // Map {
1276 * // "subObject": Map {
1277 * // "subKey": "subvalue",
1278 * // "subSubObject": Map { "subSubKey": "ha ha ha!" }
1279 * // }
1280 * // }
1281 * ```
1282 *
1283 * Plain JavaScript Object or Arrays may be nested within an Immutable.js
1284 * Collection, and setIn() can update those values as well, treating them
1285 * immutably by creating new copies of those values with the changes applied.
1286 *
1287 * <!-- runkit:activate -->
1288 * ```js
1289 * const { Map } = require('immutable')
1290 * const originalMap = Map({
1291 * subObject: {
1292 * subKey: 'subvalue',
1293 * subSubObject: {
1294 * subSubKey: 'subSubValue'
1295 * }
1296 * }
1297 * })
1298 *
1299 * originalMap.setIn(['subObject', 'subKey'], 'ha ha!')
1300 * // Map {
1301 * // "subObject": {
1302 * // subKey: "ha ha!",
1303 * // subSubObject: { subSubKey: "subSubValue" }
1304 * // }
1305 * // }
1306 * ```
1307 *
1308 * If any key in the path exists but cannot be updated (such as a primitive
1309 * like number or a custom Object like Date), an error will be thrown.
1310 *
1311 * Note: `setIn` can be used in `withMutations`.
1312 */
1313 setIn(keyPath: Iterable<unknown>, value: unknown): this;
1314
1315 /**
1316 * Returns a new Map having removed the value at this `keyPath`. If any keys
1317 * in `keyPath` do not exist, no change will occur.
1318 *
1319 * Note: `deleteIn` can be used in `withMutations`.
1320 *
1321 * @alias removeIn
1322 */
1323 deleteIn(keyPath: Iterable<unknown>): this;
1324 removeIn(keyPath: Iterable<unknown>): this;
1325
1326 /**
1327 * Returns a new Map having applied the `updater` to the entry found at the
1328 * keyPath.
1329 *
1330 * This is most commonly used to call methods on collections nested within a
1331 * structure of data. For example, in order to `.push()` onto a nested `List`,
1332 * `updateIn` and `push` can be used together:
1333 *
1334 * <!-- runkit:activate -->
1335 * ```js
1336 * const { Map, List } = require('immutable')
1337 * const map = Map({ inMap: Map({ inList: List([ 1, 2, 3 ]) }) })
1338 * const newMap = map.updateIn(['inMap', 'inList'], list => list.push(4))
1339 * // Map { "inMap": Map { "inList": List [ 1, 2, 3, 4 ] } }
1340 * ```
1341 *
1342 * If any keys in `keyPath` do not exist, new Immutable `Map`s will
1343 * be created at those keys. If the `keyPath` does not already contain a
1344 * value, the `updater` function will be called with `notSetValue`, if
1345 * provided, otherwise `undefined`.
1346 *
1347 * <!-- runkit:activate
1348 * { "preamble": "const { Map } = require('immutable')" }
1349 * -->
1350 * ```js
1351 * const map = Map({ a: Map({ b: Map({ c: 10 }) }) })
1352 * const newMap = map.updateIn(['a', 'b', 'c'], val => val * 2)
1353 * // Map { "a": Map { "b": Map { "c": 20 } } }
1354 * ```
1355 *
1356 * If the `updater` function returns the same value it was called with, then
1357 * no change will occur. This is still true if `notSetValue` is provided.
1358 *
1359 * <!-- runkit:activate
1360 * { "preamble": "const { Map } = require('immutable')" }
1361 * -->
1362 * ```js
1363 * const map = Map({ a: Map({ b: Map({ c: 10 }) }) })
1364 * const newMap = map.updateIn(['a', 'b', 'x'], 100, val => val)
1365 * // Map { "a": Map { "b": Map { "c": 10 } } }
1366 * assert.strictEqual(newMap, aMap)
1367 * ```
1368 *
1369 * For code using ES2015 or later, using `notSetValue` is discourged in
1370 * favor of function parameter default values. This helps to avoid any
1371 * potential confusion with identify functions as described above.
1372 *
1373 * The previous example behaves differently when written with default values:
1374 *
1375 * <!-- runkit:activate
1376 * { "preamble": "const { Map } = require('immutable')" }
1377 * -->
1378 * ```js
1379 * const map = Map({ a: Map({ b: Map({ c: 10 }) }) })
1380 * const newMap = map.updateIn(['a', 'b', 'x'], (val = 100) => val)
1381 * // Map { "a": Map { "b": Map { "c": 10, "x": 100 } } }
1382 * ```
1383 *
1384 * Plain JavaScript Object or Arrays may be nested within an Immutable.js
1385 * Collection, and updateIn() can update those values as well, treating them
1386 * immutably by creating new copies of those values with the changes applied.
1387 *
1388 * <!-- runkit:activate
1389 * { "preamble": "const { Map } = require('immutable')" }
1390 * -->
1391 * ```js
1392 * const map = Map({ a: { b: { c: 10 } } })
1393 * const newMap = map.updateIn(['a', 'b', 'c'], val => val * 2)
1394 * // Map { "a": { b: { c: 20 } } }
1395 * ```
1396 *
1397 * If any key in the path exists but cannot be updated (such as a primitive
1398 * like number or a custom Object like Date), an error will be thrown.
1399 *
1400 * Note: `updateIn` can be used in `withMutations`.
1401 */
1402 updateIn(
1403 keyPath: Iterable<unknown>,
1404 notSetValue: unknown,
1405 updater: (value: unknown) => unknown
1406 ): this;
1407 updateIn(
1408 keyPath: Iterable<unknown>,
1409 updater: (value: unknown) => unknown
1410 ): this;
1411
1412 /**
1413 * A combination of `updateIn` and `merge`, returning a new Map, but
1414 * performing the merge at a point arrived at by following the keyPath.
1415 * In other words, these two lines are equivalent:
1416 *
1417 * ```js
1418 * map.updateIn(['a', 'b', 'c'], abc => abc.merge(y))
1419 * map.mergeIn(['a', 'b', 'c'], y)
1420 * ```
1421 *
1422 * Note: `mergeIn` can be used in `withMutations`.
1423 */
1424 mergeIn(keyPath: Iterable<unknown>, ...collections: Array<unknown>): this;
1425
1426 /**
1427 * A combination of `updateIn` and `mergeDeep`, returning a new Map, but
1428 * performing the deep merge at a point arrived at by following the keyPath.
1429 * In other words, these two lines are equivalent:
1430 *
1431 * ```js
1432 * map.updateIn(['a', 'b', 'c'], abc => abc.mergeDeep(y))
1433 * map.mergeDeepIn(['a', 'b', 'c'], y)
1434 * ```
1435 *
1436 * Note: `mergeDeepIn` can be used in `withMutations`.
1437 */
1438 mergeDeepIn(
1439 keyPath: Iterable<unknown>,
1440 ...collections: Array<unknown>
1441 ): this;
1442
1443 // Transient changes
1444
1445 /**
1446 * Every time you call one of the above functions, a new immutable Map is
1447 * created. If a pure function calls a number of these to produce a final
1448 * return value, then a penalty on performance and memory has been paid by
1449 * creating all of the intermediate immutable Maps.
1450 *
1451 * If you need to apply a series of mutations to produce a new immutable
1452 * Map, `withMutations()` creates a temporary mutable copy of the Map which
1453 * can apply mutations in a highly performant manner. In fact, this is
1454 * exactly how complex mutations like `merge` are done.
1455 *
1456 * As an example, this results in the creation of 2, not 4, new Maps:
1457 *
1458 * <!-- runkit:activate -->
1459 * ```js
1460 * const { Map } = require('immutable')
1461 * const map1 = Map()
1462 * const map2 = map1.withMutations(map => {
1463 * map.set('a', 1).set('b', 2).set('c', 3)
1464 * })
1465 * assert.equal(map1.size, 0)
1466 * assert.equal(map2.size, 3)
1467 * ```
1468 *
1469 * Note: Not all methods can be used on a mutable collection or within
1470 * `withMutations`! Read the documentation for each method to see if it
1471 * is safe to use in `withMutations`.
1472 */
1473 withMutations(mutator: (mutable: this) => unknown): this;
1474
1475 /**
1476 * Another way to avoid creation of intermediate Immutable maps is to create
1477 * a mutable copy of this collection. Mutable copies *always* return `this`,
1478 * and thus shouldn't be used for equality. Your function should never return
1479 * a mutable copy of a collection, only use it internally to create a new
1480 * collection.
1481 *
1482 * If possible, use `withMutations` to work with temporary mutable copies as
1483 * it provides an easier to use API and considers many common optimizations.
1484 *
1485 * Note: if the collection is already mutable, `asMutable` returns itself.
1486 *
1487 * Note: Not all methods can be used on a mutable collection or within
1488 * `withMutations`! Read the documentation for each method to see if it
1489 * is safe to use in `withMutations`.
1490 *
1491 * @see `Map#asImmutable`
1492 */
1493 asMutable(): this;
1494
1495 /**
1496 * Returns true if this is a mutable copy (see `asMutable()`) and mutative
1497 * alterations have been applied.
1498 *
1499 * @see `Map#asMutable`
1500 */
1501 wasAltered(): boolean;
1502
1503 /**
1504 * The yin to `asMutable`'s yang. Because it applies to mutable collections,
1505 * this operation is *mutable* and may return itself (though may not
1506 * return itself, i.e. if the result is an empty collection). Once
1507 * performed, the original mutable copy must no longer be mutated since it
1508 * may be the immutable result.
1509 *
1510 * If possible, use `withMutations` to work with temporary mutable copies as
1511 * it provides an easier to use API and considers many common optimizations.
1512 *
1513 * @see `Map#asMutable`
1514 */
1515 asImmutable(): this;
1516
1517 // Sequence algorithms
1518
1519 /**
1520 * Returns a new Map with values passed through a
1521 * `mapper` function.
1522 *
1523 * Map({ a: 1, b: 2 }).map(x => 10 * x)
1524 * // Map { a: 10, b: 20 }
1525 */
1526 map<M>(
1527 mapper: (value: V, key: K, iter: this) => M,
1528 context?: unknown
1529 ): Map<K, M>;
1530
1531 /**
1532 * @see Collection.Keyed.mapKeys
1533 */
1534 mapKeys<M>(
1535 mapper: (key: K, value: V, iter: this) => M,
1536 context?: unknown
1537 ): Map<M, V>;
1538
1539 /**
1540 * @see Collection.Keyed.mapEntries
1541 */
1542 mapEntries<KM, VM>(
1543 mapper: (
1544 entry: [K, V],
1545 index: number,
1546 iter: this
1547 ) => [KM, VM] | undefined,
1548 context?: unknown
1549 ): Map<KM, VM>;
1550
1551 /**
1552 * Flat-maps the Map, returning a new Map.
1553 *
1554 * Similar to `data.map(...).flatten(true)`.
1555 */
1556 flatMap<KM, VM>(
1557 mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
1558 context?: unknown
1559 ): Map<KM, VM>;
1560
1561 /**
1562 * Returns a new Map with only the entries for which the `predicate`
1563 * function returns true.
1564 *
1565 * Note: `filter()` always returns a new instance, even if it results in
1566 * not filtering out any values.
1567 */
1568 filter<F extends V>(
1569 predicate: (value: V, key: K, iter: this) => value is F,
1570 context?: unknown
1571 ): Map<K, F>;
1572 filter(
1573 predicate: (value: V, key: K, iter: this) => unknown,
1574 context?: unknown
1575 ): this;
1576
1577 /**
1578 * Returns a new Map with the values for which the `predicate`
1579 * function returns false and another for which is returns true.
1580 */
1581 partition<F extends V, C>(
1582 predicate: (this: C, value: V, key: K, iter: this) => value is F,
1583 context?: C
1584 ): [Map<K, V>, Map<K, F>];
1585 partition<C>(
1586 predicate: (this: C, value: V, key: K, iter: this) => unknown,
1587 context?: C
1588 ): [this, this];
1589
1590 /**
1591 * @see Collection.Keyed.flip
1592 */
1593 flip(): Map<V, K>;
1594
1595 /**
1596 * Returns an OrderedMap of the same type which includes the same entries,
1597 * stably sorted by using a `comparator`.
1598 *
1599 * If a `comparator` is not provided, a default comparator uses `<` and `>`.
1600 *
1601 * `comparator(valueA, valueB)`:
1602 *
1603 * * Returns `0` if the elements should not be swapped.
1604 * * Returns `-1` (or any negative number) if `valueA` comes before `valueB`
1605 * * Returns `1` (or any positive number) if `valueA` comes after `valueB`
1606 * * Alternatively, can return a value of the `PairSorting` enum type
1607 * * Is pure, i.e. it must always return the same value for the same pair
1608 * of values.
1609 *
1610 * <!-- runkit:activate -->
1611 * ```js
1612 * const { Map } = require('immutable')
1613 * Map({ "c": 3, "a": 1, "b": 2 }).sort((a, b) => {
1614 * if (a < b) { return -1; }
1615 * if (a > b) { return 1; }
1616 * if (a === b) { return 0; }
1617 * });
1618 * // OrderedMap { "a": 1, "b": 2, "c": 3 }
1619 * ```
1620 *
1621 * Note: `sort()` Always returns a new instance, even if the original was
1622 * already sorted.
1623 *
1624 * Note: This is always an eager operation.
1625 */
1626 sort(comparator?: Comparator<V>): this & OrderedMap<K, V>;
1627
1628 /**
1629 * Like `sort`, but also accepts a `comparatorValueMapper` which allows for
1630 * sorting by more sophisticated means:
1631 *
1632 * <!-- runkit:activate -->
1633 * ```js
1634 * const { Map } = require('immutable')
1635 * const beattles = Map({
1636 * John: { name: "Lennon" },
1637 * Paul: { name: "McCartney" },
1638 * George: { name: "Harrison" },
1639 * Ringo: { name: "Starr" },
1640 * });
1641 * beattles.sortBy(member => member.name);
1642 * ```
1643 *
1644 * Note: `sortBy()` Always returns a new instance, even if the original was
1645 * already sorted.
1646 *
1647 * Note: This is always an eager operation.
1648 */
1649 sortBy<C>(
1650 comparatorValueMapper: (value: V, key: K, iter: this) => C,
1651 comparator?: (valueA: C, valueB: C) => number
1652 ): this & OrderedMap<K, V>;
1653 }
1654
1655 /**
1656 * A type of Map that has the additional guarantee that the iteration order of
1657 * entries will be the order in which they were set().
1658 *
1659 * The iteration behavior of OrderedMap is the same as native ES6 Map and
1660 * JavaScript Object.
1661 *
1662 * Note that `OrderedMap` are more expensive than non-ordered `Map` and may
1663 * consume more memory. `OrderedMap#set` is amortized O(log32 N), but not
1664 * stable.
1665 */
1666 namespace OrderedMap {
1667 /**
1668 * True if the provided value is an OrderedMap.
1669 */
1670 function isOrderedMap(
1671 maybeOrderedMap: unknown
1672 ): maybeOrderedMap is OrderedMap<unknown, unknown>;
1673 }
1674
1675 /**
1676 * Creates a new Immutable OrderedMap.
1677 *
1678 * Created with the same key value pairs as the provided Collection.Keyed or
1679 * JavaScript Object or expects a Collection of [K, V] tuple entries.
1680 *
1681 * The iteration order of key-value pairs provided to this constructor will
1682 * be preserved in the OrderedMap.
1683 *
1684 * let newOrderedMap = OrderedMap({key: "value"})
1685 * let newOrderedMap = OrderedMap([["key", "value"]])
1686 *
1687 * Note: `OrderedMap` is a factory function and not a class, and does not use
1688 * the `new` keyword during construction.
1689 */
1690 function OrderedMap<K, V>(collection?: Iterable<[K, V]>): OrderedMap<K, V>;
1691 function OrderedMap<V>(obj: { [key: string]: V }): OrderedMap<string, V>;
1692
1693 interface OrderedMap<K, V> extends Map<K, V> {
1694 /**
1695 * The number of entries in this OrderedMap.
1696 */
1697 readonly size: number;
1698
1699 /**
1700 * Returns a new OrderedMap also containing the new key, value pair. If an
1701 * equivalent key already exists in this OrderedMap, it will be replaced
1702 * while maintaining the existing order.
1703 *
1704 * <!-- runkit:activate -->
1705 * ```js
1706 * const { OrderedMap } = require('immutable')
1707 * const originalMap = OrderedMap({a:1, b:1, c:1})
1708 * const updatedMap = originalMap.set('b', 2)
1709 *
1710 * originalMap
1711 * // OrderedMap {a: 1, b: 1, c: 1}
1712 * updatedMap
1713 * // OrderedMap {a: 1, b: 2, c: 1}
1714 * ```
1715 *
1716 * Note: `set` can be used in `withMutations`.
1717 */
1718 set(key: K, value: V): this;
1719
1720 /**
1721 * Returns a new OrderedMap resulting from merging the provided Collections
1722 * (or JS objects) into this OrderedMap. In other words, this takes each
1723 * entry of each collection and sets it on this OrderedMap.
1724 *
1725 * Note: Values provided to `merge` are shallowly converted before being
1726 * merged. No nested values are altered.
1727 *
1728 * <!-- runkit:activate -->
1729 * ```js
1730 * const { OrderedMap } = require('immutable')
1731 * const one = OrderedMap({ a: 10, b: 20, c: 30 })
1732 * const two = OrderedMap({ b: 40, a: 50, d: 60 })
1733 * one.merge(two) // OrderedMap { "a": 50, "b": 40, "c": 30, "d": 60 }
1734 * two.merge(one) // OrderedMap { "b": 20, "a": 10, "d": 60, "c": 30 }
1735 * ```
1736 *
1737 * Note: `merge` can be used in `withMutations`.
1738 *
1739 * @alias concat
1740 */
1741 merge<KC, VC>(
1742 ...collections: Array<Iterable<[KC, VC]>>
1743 ): OrderedMap<K | KC, Exclude<V, VC> | VC>;
1744 merge<C>(
1745 ...collections: Array<{ [key: string]: C }>
1746 ): OrderedMap<K | string, Exclude<V, C> | C>;
1747
1748 concat<KC, VC>(
1749 ...collections: Array<Iterable<[KC, VC]>>
1750 ): OrderedMap<K | KC, Exclude<V, VC> | VC>;
1751 concat<C>(
1752 ...collections: Array<{ [key: string]: C }>
1753 ): OrderedMap<K | string, Exclude<V, C> | C>;
1754
1755 mergeWith<KC, VC, VCC>(
1756 merger: (oldVal: V, newVal: VC, key: K) => VCC,
1757 ...collections: Array<Iterable<[KC, VC]>>
1758 ): OrderedMap<K | KC, V | VC | VCC>;
1759 mergeWith<C, CC>(
1760 merger: (oldVal: V, newVal: C, key: string) => CC,
1761 ...collections: Array<{ [key: string]: C }>
1762 ): OrderedMap<K | string, V | C | CC>;
1763
1764 mergeDeep<KC, VC>(
1765 ...collections: Array<Iterable<[KC, VC]>>
1766 ): OrderedMap<K | KC, V | VC>;
1767 mergeDeep<C>(
1768 ...collections: Array<{ [key: string]: C }>
1769 ): OrderedMap<K | string, V | C>;
1770
1771 // Sequence algorithms
1772
1773 /**
1774 * Returns a new OrderedMap with values passed through a
1775 * `mapper` function.
1776 *
1777 * OrderedMap({ a: 1, b: 2 }).map(x => 10 * x)
1778 * // OrderedMap { "a": 10, "b": 20 }
1779 *
1780 * Note: `map()` always returns a new instance, even if it produced the same
1781 * value at every step.
1782 */
1783 map<M>(
1784 mapper: (value: V, key: K, iter: this) => M,
1785 context?: unknown
1786 ): OrderedMap<K, M>;
1787
1788 /**
1789 * @see Collection.Keyed.mapKeys
1790 */
1791 mapKeys<M>(
1792 mapper: (key: K, value: V, iter: this) => M,
1793 context?: unknown
1794 ): OrderedMap<M, V>;
1795
1796 /**
1797 * @see Collection.Keyed.mapEntries
1798 */
1799 mapEntries<KM, VM>(
1800 mapper: (
1801 entry: [K, V],
1802 index: number,
1803 iter: this
1804 ) => [KM, VM] | undefined,
1805 context?: unknown
1806 ): OrderedMap<KM, VM>;
1807
1808 /**
1809 * Flat-maps the OrderedMap, returning a new OrderedMap.
1810 *
1811 * Similar to `data.map(...).flatten(true)`.
1812 */
1813 flatMap<KM, VM>(
1814 mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
1815 context?: unknown
1816 ): OrderedMap<KM, VM>;
1817
1818 /**
1819 * Returns a new OrderedMap with only the entries for which the `predicate`
1820 * function returns true.
1821 *
1822 * Note: `filter()` always returns a new instance, even if it results in
1823 * not filtering out any values.
1824 */
1825 filter<F extends V>(
1826 predicate: (value: V, key: K, iter: this) => value is F,
1827 context?: unknown
1828 ): OrderedMap<K, F>;
1829 filter(
1830 predicate: (value: V, key: K, iter: this) => unknown,
1831 context?: unknown
1832 ): this;
1833
1834 /**
1835 * Returns a new OrderedMap with the values for which the `predicate`
1836 * function returns false and another for which is returns true.
1837 */
1838 partition<F extends V, C>(
1839 predicate: (this: C, value: V, key: K, iter: this) => value is F,
1840 context?: C
1841 ): [OrderedMap<K, V>, OrderedMap<K, F>];
1842 partition<C>(
1843 predicate: (this: C, value: V, key: K, iter: this) => unknown,
1844 context?: C
1845 ): [this, this];
1846
1847 /**
1848 * @see Collection.Keyed.flip
1849 */
1850 flip(): OrderedMap<V, K>;
1851 }
1852
1853 /**
1854 * A Collection of unique values with `O(log32 N)` adds and has.
1855 *
1856 * When iterating a Set, the entries will be (value, value) pairs. Iteration
1857 * order of a Set is undefined, however is stable. Multiple iterations of the
1858 * same Set will iterate in the same order.
1859 *
1860 * Set values, like Map keys, may be of any type. Equality is determined using
1861 * `Immutable.is`, enabling Sets to uniquely include other Immutable
1862 * collections, custom value types, and NaN.
1863 */
1864 namespace Set {
1865 /**
1866 * True if the provided value is a Set
1867 */
1868 function isSet(maybeSet: unknown): maybeSet is Set<unknown>;
1869
1870 /**
1871 * Creates a new Set containing `values`.
1872 */
1873 function of<T>(...values: Array<T>): Set<T>;
1874
1875 /**
1876 * `Set.fromKeys()` creates a new immutable Set containing the keys from
1877 * this Collection or JavaScript Object.
1878 */
1879 function fromKeys<T>(iter: Collection.Keyed<T, unknown>): Set<T>;
1880 function fromKeys<T>(iter: Collection<T, unknown>): Set<T>;
1881 function fromKeys(obj: { [key: string]: unknown }): Set<string>;
1882
1883 /**
1884 * `Set.intersect()` creates a new immutable Set that is the intersection of
1885 * a collection of other sets.
1886 *
1887 * ```js
1888 * const { Set } = require('immutable')
1889 * const intersected = Set.intersect([
1890 * Set([ 'a', 'b', 'c' ])
1891 * Set([ 'c', 'a', 't' ])
1892 * ])
1893 * // Set [ "a", "c" ]
1894 * ```
1895 */
1896 function intersect<T>(sets: Iterable<Iterable<T>>): Set<T>;
1897
1898 /**
1899 * `Set.union()` creates a new immutable Set that is the union of a
1900 * collection of other sets.
1901 *
1902 * ```js
1903 * const { Set } = require('immutable')
1904 * const unioned = Set.union([
1905 * Set([ 'a', 'b', 'c' ])
1906 * Set([ 'c', 'a', 't' ])
1907 * ])
1908 * // Set [ "a", "b", "c", "t" ]
1909 * ```
1910 */
1911 function union<T>(sets: Iterable<Iterable<T>>): Set<T>;
1912 }
1913
1914 /**
1915 * Create a new immutable Set containing the values of the provided
1916 * collection-like.
1917 *
1918 * Note: `Set` is a factory function and not a class, and does not use the
1919 * `new` keyword during construction.
1920 */
1921 function Set<T>(collection?: Iterable<T> | ArrayLike<T>): Set<T>;
1922
1923 interface Set<T> extends Collection.Set<T> {
1924 /**
1925 * The number of items in this Set.
1926 */
1927 readonly size: number;
1928
1929 // Persistent changes
1930
1931 /**
1932 * Returns a new Set which also includes this value.
1933 *
1934 * Note: `add` can be used in `withMutations`.
1935 */
1936 add(value: T): this;
1937
1938 /**
1939 * Returns a new Set which excludes this value.
1940 *
1941 * Note: `delete` can be used in `withMutations`.
1942 *
1943 * Note: `delete` **cannot** be safely used in IE8, use `remove` if
1944 * supporting old browsers.
1945 *
1946 * @alias remove
1947 */
1948 delete(value: T): this;
1949 remove(value: T): this;
1950
1951 /**
1952 * Returns a new Set containing no values.
1953 *
1954 * Note: `clear` can be used in `withMutations`.
1955 */
1956 clear(): this;
1957
1958 /**
1959 * Returns a Set including any value from `collections` that does not already
1960 * exist in this Set.
1961 *
1962 * Note: `union` can be used in `withMutations`.
1963 * @alias merge
1964 * @alias concat
1965 */
1966 union<C>(...collections: Array<Iterable<C>>): Set<T | C>;
1967 merge<C>(...collections: Array<Iterable<C>>): Set<T | C>;
1968 concat<C>(...collections: Array<Iterable<C>>): Set<T | C>;
1969
1970 /**
1971 * Returns a Set which has removed any values not also contained
1972 * within `collections`.
1973 *
1974 * Note: `intersect` can be used in `withMutations`.
1975 */
1976 intersect(...collections: Array<Iterable<T>>): this;
1977
1978 /**
1979 * Returns a Set excluding any values contained within `collections`.
1980 *
1981 * <!-- runkit:activate -->
1982 * ```js
1983 * const { OrderedSet } = require('immutable')
1984 * OrderedSet([ 1, 2, 3 ]).subtract([1, 3])
1985 * // OrderedSet [2]
1986 * ```
1987 *
1988 * Note: `subtract` can be used in `withMutations`.
1989 */
1990 subtract(...collections: Array<Iterable<T>>): this;
1991
1992 // Transient changes
1993
1994 /**
1995 * Note: Not all methods can be used on a mutable collection or within
1996 * `withMutations`! Check the documentation for each method to see if it
1997 * mentions being safe to use in `withMutations`.
1998 *
1999 * @see `Map#withMutations`
2000 */
2001 withMutations(mutator: (mutable: this) => unknown): this;
2002
2003 /**
2004 * Note: Not all methods can be used on a mutable collection or within
2005 * `withMutations`! Check the documentation for each method to see if it
2006 * mentions being safe to use in `withMutations`.
2007 *
2008 * @see `Map#asMutable`
2009 */
2010 asMutable(): this;
2011
2012 /**
2013 * @see `Map#wasAltered`
2014 */
2015 wasAltered(): boolean;
2016
2017 /**
2018 * @see `Map#asImmutable`
2019 */
2020 asImmutable(): this;
2021
2022 // Sequence algorithms
2023
2024 /**
2025 * Returns a new Set with values passed through a
2026 * `mapper` function.
2027 *
2028 * Set([1,2]).map(x => 10 * x)
2029 * // Set [10,20]
2030 */
2031 map<M>(
2032 mapper: (value: T, key: T, iter: this) => M,
2033 context?: unknown
2034 ): Set<M>;
2035
2036 /**
2037 * Flat-maps the Set, returning a new Set.
2038 *
2039 * Similar to `set.map(...).flatten(true)`.
2040 */
2041 flatMap<M>(
2042 mapper: (value: T, key: T, iter: this) => Iterable<M>,
2043 context?: unknown
2044 ): Set<M>;
2045
2046 /**
2047 * Returns a new Set with only the values for which the `predicate`
2048 * function returns true.
2049 *
2050 * Note: `filter()` always returns a new instance, even if it results in
2051 * not filtering out any values.
2052 */
2053 filter<F extends T>(
2054 predicate: (value: T, key: T, iter: this) => value is F,
2055 context?: unknown
2056 ): Set<F>;
2057 filter(
2058 predicate: (value: T, key: T, iter: this) => unknown,
2059 context?: unknown
2060 ): this;
2061
2062 /**
2063 * Returns a new Set with the values for which the `predicate` function
2064 * returns false and another for which is returns true.
2065 */
2066 partition<F extends T, C>(
2067 predicate: (this: C, value: T, key: T, iter: this) => value is F,
2068 context?: C
2069 ): [Set<T>, Set<F>];
2070 partition<C>(
2071 predicate: (this: C, value: T, key: T, iter: this) => unknown,
2072 context?: C
2073 ): [this, this];
2074
2075 /**
2076 * Returns an OrderedSet of the same type which includes the same entries,
2077 * stably sorted by using a `comparator`.
2078 *
2079 * If a `comparator` is not provided, a default comparator uses `<` and `>`.
2080 *
2081 * `comparator(valueA, valueB)`:
2082 *
2083 * * Returns `0` if the elements should not be swapped.
2084 * * Returns `-1` (or any negative number) if `valueA` comes before `valueB`
2085 * * Returns `1` (or any positive number) if `valueA` comes after `valueB`
2086 * * Alternatively, can return a value of the `PairSorting` enum type
2087 * * Is pure, i.e. it must always return the same value for the same pair
2088 * of values.
2089 *
2090 * <!-- runkit:activate -->
2091 * ```js
2092 * const { Set } = require('immutable')
2093 * Set(['b', 'a', 'c']).sort((a, b) => {
2094 * if (a < b) { return -1; }
2095 * if (a > b) { return 1; }
2096 * if (a === b) { return 0; }
2097 * });
2098 * // OrderedSet { "a":, "b", "c" }
2099 * ```
2100 *
2101 * Note: `sort()` Always returns a new instance, even if the original was
2102 * already sorted.
2103 *
2104 * Note: This is always an eager operation.
2105 */
2106 sort(comparator?: Comparator<T>): this & OrderedSet<T>;
2107
2108 /**
2109 * Like `sort`, but also accepts a `comparatorValueMapper` which allows for
2110 * sorting by more sophisticated means:
2111 *
2112 * <!-- runkit:activate -->
2113 * ```js
2114 * const { Set } = require('immutable')
2115 * const beattles = Set([
2116 * { name: "Lennon" },
2117 * { name: "McCartney" },
2118 * { name: "Harrison" },
2119 * { name: "Starr" },
2120 * ]);
2121 * beattles.sortBy(member => member.name);
2122 * ```
2123 *
2124 * Note: `sortBy()` Always returns a new instance, even if the original was
2125 * already sorted.
2126 *
2127 * Note: This is always an eager operation.
2128 */
2129 sortBy<C>(
2130 comparatorValueMapper: (value: T, key: T, iter: this) => C,
2131 comparator?: (valueA: C, valueB: C) => number
2132 ): this & OrderedSet<T>;
2133 }
2134
2135 /**
2136 * A type of Set that has the additional guarantee that the iteration order of
2137 * values will be the order in which they were `add`ed.
2138 *
2139 * The iteration behavior of OrderedSet is the same as native ES6 Set.
2140 *
2141 * Note that `OrderedSet` are more expensive than non-ordered `Set` and may
2142 * consume more memory. `OrderedSet#add` is amortized O(log32 N), but not
2143 * stable.
2144 */
2145 namespace OrderedSet {
2146 /**
2147 * True if the provided value is an OrderedSet.
2148 */
2149 function isOrderedSet(
2150 maybeOrderedSet: unknown
2151 ): maybeOrderedSet is OrderedSet<unknown>;
2152
2153 /**
2154 * Creates a new OrderedSet containing `values`.
2155 */
2156 function of<T>(...values: Array<T>): OrderedSet<T>;
2157
2158 /**
2159 * `OrderedSet.fromKeys()` creates a new immutable OrderedSet containing
2160 * the keys from this Collection or JavaScript Object.
2161 */
2162 function fromKeys<T>(iter: Collection.Keyed<T, unknown>): OrderedSet<T>;
2163 function fromKeys<T>(iter: Collection<T, unknown>): OrderedSet<T>;
2164 function fromKeys(obj: { [key: string]: unknown }): OrderedSet<string>;
2165 }
2166
2167 /**
2168 * Create a new immutable OrderedSet containing the values of the provided
2169 * collection-like.
2170 *
2171 * Note: `OrderedSet` is a factory function and not a class, and does not use
2172 * the `new` keyword during construction.
2173 */
2174 function OrderedSet<T>(
2175 collection?: Iterable<T> | ArrayLike<T>
2176 ): OrderedSet<T>;
2177
2178 interface OrderedSet<T> extends Set<T> {
2179 /**
2180 * The number of items in this OrderedSet.
2181 */
2182 readonly size: number;
2183
2184 /**
2185 * Returns an OrderedSet including any value from `collections` that does
2186 * not already exist in this OrderedSet.
2187 *
2188 * Note: `union` can be used in `withMutations`.
2189 * @alias merge
2190 * @alias concat
2191 */
2192 union<C>(...collections: Array<Iterable<C>>): OrderedSet<T | C>;
2193 merge<C>(...collections: Array<Iterable<C>>): OrderedSet<T | C>;
2194 concat<C>(...collections: Array<Iterable<C>>): OrderedSet<T | C>;
2195
2196 // Sequence algorithms
2197
2198 /**
2199 * Returns a new Set with values passed through a
2200 * `mapper` function.
2201 *
2202 * OrderedSet([ 1, 2 ]).map(x => 10 * x)
2203 * // OrderedSet [10, 20]
2204 */
2205 map<M>(
2206 mapper: (value: T, key: T, iter: this) => M,
2207 context?: unknown
2208 ): OrderedSet<M>;
2209
2210 /**
2211 * Flat-maps the OrderedSet, returning a new OrderedSet.
2212 *
2213 * Similar to `set.map(...).flatten(true)`.
2214 */
2215 flatMap<M>(
2216 mapper: (value: T, key: T, iter: this) => Iterable<M>,
2217 context?: unknown
2218 ): OrderedSet<M>;
2219
2220 /**
2221 * Returns a new OrderedSet with only the values for which the `predicate`
2222 * function returns true.
2223 *
2224 * Note: `filter()` always returns a new instance, even if it results in
2225 * not filtering out any values.
2226 */
2227 filter<F extends T>(
2228 predicate: (value: T, key: T, iter: this) => value is F,
2229 context?: unknown
2230 ): OrderedSet<F>;
2231 filter(
2232 predicate: (value: T, key: T, iter: this) => unknown,
2233 context?: unknown
2234 ): this;
2235
2236 /**
2237 * Returns a new OrderedSet with the values for which the `predicate`
2238 * function returns false and another for which is returns true.
2239 */
2240 partition<F extends T, C>(
2241 predicate: (this: C, value: T, key: T, iter: this) => value is F,
2242 context?: C
2243 ): [OrderedSet<T>, OrderedSet<F>];
2244 partition<C>(
2245 predicate: (this: C, value: T, key: T, iter: this) => unknown,
2246 context?: C
2247 ): [this, this];
2248
2249 /**
2250 * Returns an OrderedSet of the same type "zipped" with the provided
2251 * collections.
2252 *
2253 * Like `zipWith`, but using the default `zipper`: creating an `Array`.
2254 *
2255 * ```js
2256 * const a = OrderedSet([ 1, 2, 3 ])
2257 * const b = OrderedSet([ 4, 5, 6 ])
2258 * const c = a.zip(b)
2259 * // OrderedSet [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
2260 * ```
2261 */
2262 zip<U>(other: Collection<unknown, U>): OrderedSet<[T, U]>;
2263 zip<U, V>(
2264 other1: Collection<unknown, U>,
2265 other2: Collection<unknown, V>
2266 ): OrderedSet<[T, U, V]>;
2267 zip(
2268 ...collections: Array<Collection<unknown, unknown>>
2269 ): OrderedSet<unknown>;
2270
2271 /**
2272 * Returns a OrderedSet of the same type "zipped" with the provided
2273 * collections.
2274 *
2275 * Unlike `zip`, `zipAll` continues zipping until the longest collection is
2276 * exhausted. Missing values from shorter collections are filled with `undefined`.
2277 *
2278 * ```js
2279 * const a = OrderedSet([ 1, 2 ]);
2280 * const b = OrderedSet([ 3, 4, 5 ]);
2281 * const c = a.zipAll(b); // OrderedSet [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ]
2282 * ```
2283 *
2284 * Note: Since zipAll will return a collection as large as the largest
2285 * input, some results may contain undefined values. TypeScript cannot
2286 * account for these without cases (as of v2.5).
2287 */
2288 zipAll<U>(other: Collection<unknown, U>): OrderedSet<[T, U]>;
2289 zipAll<U, V>(
2290 other1: Collection<unknown, U>,
2291 other2: Collection<unknown, V>
2292 ): OrderedSet<[T, U, V]>;
2293 zipAll(
2294 ...collections: Array<Collection<unknown, unknown>>
2295 ): OrderedSet<unknown>;
2296
2297 /**
2298 * Returns an OrderedSet of the same type "zipped" with the provided
2299 * collections by using a custom `zipper` function.
2300 *
2301 * @see Seq.Indexed.zipWith
2302 */
2303 zipWith<U, Z>(
2304 zipper: (value: T, otherValue: U) => Z,
2305 otherCollection: Collection<unknown, U>
2306 ): OrderedSet<Z>;
2307 zipWith<U, V, Z>(
2308 zipper: (value: T, otherValue: U, thirdValue: V) => Z,
2309 otherCollection: Collection<unknown, U>,
2310 thirdCollection: Collection<unknown, V>
2311 ): OrderedSet<Z>;
2312 zipWith<Z>(
2313 zipper: (...values: Array<unknown>) => Z,
2314 ...collections: Array<Collection<unknown, unknown>>
2315 ): OrderedSet<Z>;
2316 }
2317
2318 /**
2319 * Stacks are indexed collections which support very efficient O(1) addition
2320 * and removal from the front using `unshift(v)` and `shift()`.
2321 *
2322 * For familiarity, Stack also provides `push(v)`, `pop()`, and `peek()`, but
2323 * be aware that they also operate on the front of the list, unlike List or
2324 * a JavaScript Array.
2325 *
2326 * Note: `reverse()` or any inherent reverse traversal (`reduceRight`,
2327 * `lastIndexOf`, etc.) is not efficient with a Stack.
2328 *
2329 * Stack is implemented with a Single-Linked List.
2330 */
2331 namespace Stack {
2332 /**
2333 * True if the provided value is a Stack
2334 */
2335 function isStack(maybeStack: unknown): maybeStack is Stack<unknown>;
2336
2337 /**
2338 * Creates a new Stack containing `values`.
2339 */
2340 function of<T>(...values: Array<T>): Stack<T>;
2341 }
2342
2343 /**
2344 * Create a new immutable Stack containing the values of the provided
2345 * collection-like.
2346 *
2347 * The iteration order of the provided collection is preserved in the
2348 * resulting `Stack`.
2349 *
2350 * Note: `Stack` is a factory function and not a class, and does not use the
2351 * `new` keyword during construction.
2352 */
2353 function Stack<T>(collection?: Iterable<T> | ArrayLike<T>): Stack<T>;
2354
2355 interface Stack<T> extends Collection.Indexed<T> {
2356 /**
2357 * The number of items in this Stack.
2358 */
2359 readonly size: number;
2360
2361 // Reading values
2362
2363 /**
2364 * Alias for `Stack.first()`.
2365 */
2366 peek(): T | undefined;
2367
2368 // Persistent changes
2369
2370 /**
2371 * Returns a new Stack with 0 size and no values.
2372 *
2373 * Note: `clear` can be used in `withMutations`.
2374 */
2375 clear(): Stack<T>;
2376
2377 /**
2378 * Returns a new Stack with the provided `values` prepended, shifting other
2379 * values ahead to higher indices.
2380 *
2381 * This is very efficient for Stack.
2382 *
2383 * Note: `unshift` can be used in `withMutations`.
2384 */
2385 unshift(...values: Array<T>): Stack<T>;
2386
2387 /**
2388 * Like `Stack#unshift`, but accepts a collection rather than varargs.
2389 *
2390 * Note: `unshiftAll` can be used in `withMutations`.
2391 */
2392 unshiftAll(iter: Iterable<T>): Stack<T>;
2393
2394 /**
2395 * Returns a new Stack with a size ones less than this Stack, excluding
2396 * the first item in this Stack, shifting all other values to a lower index.
2397 *
2398 * Note: this differs from `Array#shift` because it returns a new
2399 * Stack rather than the removed value. Use `first()` or `peek()` to get the
2400 * first value in this Stack.
2401 *
2402 * Note: `shift` can be used in `withMutations`.
2403 */
2404 shift(): Stack<T>;
2405
2406 /**
2407 * Alias for `Stack#unshift` and is not equivalent to `List#push`.
2408 */
2409 push(...values: Array<T>): Stack<T>;
2410
2411 /**
2412 * Alias for `Stack#unshiftAll`.
2413 */
2414 pushAll(iter: Iterable<T>): Stack<T>;
2415
2416 /**
2417 * Alias for `Stack#shift` and is not equivalent to `List#pop`.
2418 */
2419 pop(): Stack<T>;
2420
2421 // Transient changes
2422
2423 /**
2424 * Note: Not all methods can be used on a mutable collection or within
2425 * `withMutations`! Check the documentation for each method to see if it
2426 * mentions being safe to use in `withMutations`.
2427 *
2428 * @see `Map#withMutations`
2429 */
2430 withMutations(mutator: (mutable: this) => unknown): this;
2431
2432 /**
2433 * Note: Not all methods can be used on a mutable collection or within
2434 * `withMutations`! Check the documentation for each method to see if it
2435 * mentions being safe to use in `withMutations`.
2436 *
2437 * @see `Map#asMutable`
2438 */
2439 asMutable(): this;
2440
2441 /**
2442 * @see `Map#wasAltered`
2443 */
2444 wasAltered(): boolean;
2445
2446 /**
2447 * @see `Map#asImmutable`
2448 */
2449 asImmutable(): this;
2450
2451 // Sequence algorithms
2452
2453 /**
2454 * Returns a new Stack with other collections concatenated to this one.
2455 */
2456 concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Stack<T | C>;
2457
2458 /**
2459 * Returns a new Stack with values passed through a
2460 * `mapper` function.
2461 *
2462 * Stack([ 1, 2 ]).map(x => 10 * x)
2463 * // Stack [ 10, 20 ]
2464 *
2465 * Note: `map()` always returns a new instance, even if it produced the same
2466 * value at every step.
2467 */
2468 map<M>(
2469 mapper: (value: T, key: number, iter: this) => M,
2470 context?: unknown
2471 ): Stack<M>;
2472
2473 /**
2474 * Flat-maps the Stack, returning a new Stack.
2475 *
2476 * Similar to `stack.map(...).flatten(true)`.
2477 */
2478 flatMap<M>(
2479 mapper: (value: T, key: number, iter: this) => Iterable<M>,
2480 context?: unknown
2481 ): Stack<M>;
2482
2483 /**
2484 * Returns a new Set with only the values for which the `predicate`
2485 * function returns true.
2486 *
2487 * Note: `filter()` always returns a new instance, even if it results in
2488 * not filtering out any values.
2489 */
2490 filter<F extends T>(
2491 predicate: (value: T, index: number, iter: this) => value is F,
2492 context?: unknown
2493 ): Set<F>;
2494 filter(
2495 predicate: (value: T, index: number, iter: this) => unknown,
2496 context?: unknown
2497 ): this;
2498
2499 /**
2500 * Returns a Stack "zipped" with the provided collections.
2501 *
2502 * Like `zipWith`, but using the default `zipper`: creating an `Array`.
2503 *
2504 * ```js
2505 * const a = Stack([ 1, 2, 3 ]);
2506 * const b = Stack([ 4, 5, 6 ]);
2507 * const c = a.zip(b); // Stack [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
2508 * ```
2509 */
2510 zip<U>(other: Collection<unknown, U>): Stack<[T, U]>;
2511 zip<U, V>(
2512 other: Collection<unknown, U>,
2513 other2: Collection<unknown, V>
2514 ): Stack<[T, U, V]>;
2515 zip(...collections: Array<Collection<unknown, unknown>>): Stack<unknown>;
2516
2517 /**
2518 * Returns a Stack "zipped" with the provided collections.
2519 *
2520 * Unlike `zip`, `zipAll` continues zipping until the longest collection is
2521 * exhausted. Missing values from shorter collections are filled with `undefined`.
2522 *
2523 * ```js
2524 * const a = Stack([ 1, 2 ]);
2525 * const b = Stack([ 3, 4, 5 ]);
2526 * const c = a.zipAll(b); // Stack [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ]
2527 * ```
2528 *
2529 * Note: Since zipAll will return a collection as large as the largest
2530 * input, some results may contain undefined values. TypeScript cannot
2531 * account for these without cases (as of v2.5).
2532 */
2533 zipAll<U>(other: Collection<unknown, U>): Stack<[T, U]>;
2534 zipAll<U, V>(
2535 other: Collection<unknown, U>,
2536 other2: Collection<unknown, V>
2537 ): Stack<[T, U, V]>;
2538 zipAll(...collections: Array<Collection<unknown, unknown>>): Stack<unknown>;
2539
2540 /**
2541 * Returns a Stack "zipped" with the provided collections by using a
2542 * custom `zipper` function.
2543 *
2544 * ```js
2545 * const a = Stack([ 1, 2, 3 ]);
2546 * const b = Stack([ 4, 5, 6 ]);
2547 * const c = a.zipWith((a, b) => a + b, b);
2548 * // Stack [ 5, 7, 9 ]
2549 * ```
2550 */
2551 zipWith<U, Z>(
2552 zipper: (value: T, otherValue: U) => Z,
2553 otherCollection: Collection<unknown, U>
2554 ): Stack<Z>;
2555 zipWith<U, V, Z>(
2556 zipper: (value: T, otherValue: U, thirdValue: V) => Z,
2557 otherCollection: Collection<unknown, U>,
2558 thirdCollection: Collection<unknown, V>
2559 ): Stack<Z>;
2560 zipWith<Z>(
2561 zipper: (...values: Array<unknown>) => Z,
2562 ...collections: Array<Collection<unknown, unknown>>
2563 ): Stack<Z>;
2564 }
2565
2566 /**
2567 * Returns a Seq.Indexed of numbers from `start` (inclusive) to `end`
2568 * (exclusive), by `step`, where `start` defaults to 0, `step` to 1, and `end` to
2569 * infinity. When `start` is equal to `end`, returns empty range.
2570 *
2571 * Note: `Range` is a factory function and not a class, and does not use the
2572 * `new` keyword during construction.
2573 *
2574 * ```js
2575 * const { Range } = require('immutable')
2576 * Range() // [ 0, 1, 2, 3, ... ]
2577 * Range(10) // [ 10, 11, 12, 13, ... ]
2578 * Range(10, 15) // [ 10, 11, 12, 13, 14 ]
2579 * Range(10, 30, 5) // [ 10, 15, 20, 25 ]
2580 * Range(30, 10, 5) // [ 30, 25, 20, 15 ]
2581 * Range(30, 30, 5) // []
2582 * ```
2583 */
2584 function Range(
2585 start: number,
2586 end: number,
2587 step?: number
2588 ): Seq.Indexed<number>;
2589
2590 /**
2591 * Returns a Seq.Indexed of `value` repeated `times` times. When `times` is
2592 * not defined, returns an infinite `Seq` of `value`.
2593 *
2594 * Note: `Repeat` is a factory function and not a class, and does not use the
2595 * `new` keyword during construction.
2596 *
2597 * ```js
2598 * const { Repeat } = require('immutable')
2599 * Repeat('foo') // [ 'foo', 'foo', 'foo', ... ]
2600 * Repeat('bar', 4) // [ 'bar', 'bar', 'bar', 'bar' ]
2601 * ```
2602 */
2603 function Repeat<T>(value: T, times?: number): Seq.Indexed<T>;
2604
2605 /**
2606 * A record is similar to a JS object, but enforces a specific set of allowed
2607 * string keys, and has default values.
2608 *
2609 * The `Record()` function produces new Record Factories, which when called
2610 * create Record instances.
2611 *
2612 * ```js
2613 * const { Record } = require('immutable')
2614 * const ABRecord = Record({ a: 1, b: 2 })
2615 * const myRecord = ABRecord({ b: 3 })
2616 * ```
2617 *
2618 * Records always have a value for the keys they define. `remove`ing a key
2619 * from a record simply resets it to the default value for that key.
2620 *
2621 * ```js
2622 * myRecord.get('a') // 1
2623 * myRecord.get('b') // 3
2624 * const myRecordWithoutB = myRecord.remove('b')
2625 * myRecordWithoutB.get('b') // 2
2626 * ```
2627 *
2628 * Values provided to the constructor not found in the Record type will
2629 * be ignored. For example, in this case, ABRecord is provided a key "x" even
2630 * though only "a" and "b" have been defined. The value for "x" will be
2631 * ignored for this record.
2632 *
2633 * ```js
2634 * const myRecord = ABRecord({ b: 3, x: 10 })
2635 * myRecord.get('x') // undefined
2636 * ```
2637 *
2638 * Because Records have a known set of string keys, property get access works
2639 * as expected, however property sets will throw an Error.
2640 *
2641 * Note: IE8 does not support property access. Only use `get()` when
2642 * supporting IE8.
2643 *
2644 * ```js
2645 * myRecord.b // 3
2646 * myRecord.b = 5 // throws Error
2647 * ```
2648 *
2649 * Record Types can be extended as well, allowing for custom methods on your
2650 * Record. This is not a common pattern in functional environments, but is in
2651 * many JS programs.
2652 *
2653 * However Record Types are more restricted than typical JavaScript classes.
2654 * They do not use a class constructor, which also means they cannot use
2655 * class properties (since those are technically part of a constructor).
2656 *
2657 * While Record Types can be syntactically created with the JavaScript `class`
2658 * form, the resulting Record function is actually a factory function, not a
2659 * class constructor. Even though Record Types are not classes, JavaScript
2660 * currently requires the use of `new` when creating new Record instances if
2661 * they are defined as a `class`.
2662 *
2663 * ```
2664 * class ABRecord extends Record({ a: 1, b: 2 }) {
2665 * getAB() {
2666 * return this.a + this.b;
2667 * }
2668 * }
2669 *
2670 * var myRecord = new ABRecord({b: 3})
2671 * myRecord.getAB() // 4
2672 * ```
2673 *
2674 *
2675 * **Flow Typing Records:**
2676 *
2677 * Immutable.js exports two Flow types designed to make it easier to use
2678 * Records with flow typed code, `RecordOf<TProps>` and `RecordFactory<TProps>`.
2679 *
2680 * When defining a new kind of Record factory function, use a flow type that
2681 * describes the values the record contains along with `RecordFactory<TProps>`.
2682 * To type instances of the Record (which the factory function returns),
2683 * use `RecordOf<TProps>`.
2684 *
2685 * Typically, new Record definitions will export both the Record factory
2686 * function as well as the Record instance type for use in other code.
2687 *
2688 * ```js
2689 * import type { RecordFactory, RecordOf } from 'immutable';
2690 *
2691 * // Use RecordFactory<TProps> for defining new Record factory functions.
2692 * type Point3DProps = { x: number, y: number, z: number };
2693 * const defaultValues: Point3DProps = { x: 0, y: 0, z: 0 };
2694 * const makePoint3D: RecordFactory<Point3DProps> = Record(defaultValues);
2695 * export makePoint3D;
2696 *
2697 * // Use RecordOf<T> for defining new instances of that Record.
2698 * export type Point3D = RecordOf<Point3DProps>;
2699 * const some3DPoint: Point3D = makePoint3D({ x: 10, y: 20, z: 30 });
2700 * ```
2701 *
2702 * **Flow Typing Record Subclasses:**
2703 *
2704 * Records can be subclassed as a means to add additional methods to Record
2705 * instances. This is generally discouraged in favor of a more functional API,
2706 * since Subclasses have some minor overhead. However the ability to create
2707 * a rich API on Record types can be quite valuable.
2708 *
2709 * When using Flow to type Subclasses, do not use `RecordFactory<TProps>`,
2710 * instead apply the props type when subclassing:
2711 *
2712 * ```js
2713 * type PersonProps = {name: string, age: number};
2714 * const defaultValues: PersonProps = {name: 'Aristotle', age: 2400};
2715 * const PersonRecord = Record(defaultValues);
2716 * class Person extends PersonRecord<PersonProps> {
2717 * getName(): string {
2718 * return this.get('name')
2719 * }
2720 *
2721 * setName(name: string): this {
2722 * return this.set('name', name);
2723 * }
2724 * }
2725 * ```
2726 *
2727 * **Choosing Records vs plain JavaScript objects**
2728 *
2729 * Records offer a persistently immutable alternative to plain JavaScript
2730 * objects, however they're not required to be used within Immutable.js
2731 * collections. In fact, the deep-access and deep-updating functions
2732 * like `getIn()` and `setIn()` work with plain JavaScript Objects as well.
2733 *
2734 * Deciding to use Records or Objects in your application should be informed
2735 * by the tradeoffs and relative benefits of each:
2736 *
2737 * - *Runtime immutability*: plain JS objects may be carefully treated as
2738 * immutable, however Record instances will *throw* if attempted to be
2739 * mutated directly. Records provide this additional guarantee, however at
2740 * some marginal runtime cost. While JS objects are mutable by nature, the
2741 * use of type-checking tools like [Flow](https://medium.com/@gcanti/immutability-with-flow-faa050a1aef4)
2742 * can help gain confidence in code written to favor immutability.
2743 *
2744 * - *Value equality*: Records use value equality when compared with `is()`
2745 * or `record.equals()`. That is, two Records with the same keys and values
2746 * are equal. Plain objects use *reference equality*. Two objects with the
2747 * same keys and values are not equal since they are different objects.
2748 * This is important to consider when using objects as keys in a `Map` or
2749 * values in a `Set`, which use equality when retrieving values.
2750 *
2751 * - *API methods*: Records have a full featured API, with methods like
2752 * `.getIn()`, and `.equals()`. These can make working with these values
2753 * easier, but comes at the cost of not allowing keys with those names.
2754 *
2755 * - *Default values*: Records provide default values for every key, which
2756 * can be useful when constructing Records with often unchanging values.
2757 * However default values can make using Flow and TypeScript more laborious.
2758 *
2759 * - *Serialization*: Records use a custom internal representation to
2760 * efficiently store and update their values. Converting to and from this
2761 * form isn't free. If converting Records to plain objects is common,
2762 * consider sticking with plain objects to begin with.
2763 */
2764 namespace Record {
2765 /**
2766 * True if `maybeRecord` is an instance of a Record.
2767 */
2768 function isRecord(maybeRecord: unknown): maybeRecord is Record<{}>;
2769
2770 /**
2771 * Records allow passing a second parameter to supply a descriptive name
2772 * that appears when converting a Record to a string or in any error
2773 * messages. A descriptive name for any record can be accessed by using this
2774 * method. If one was not provided, the string "Record" is returned.
2775 *
2776 * ```js
2777 * const { Record } = require('immutable')
2778 * const Person = Record({
2779 * name: null
2780 * }, 'Person')
2781 *
2782 * var me = Person({ name: 'My Name' })
2783 * me.toString() // "Person { "name": "My Name" }"
2784 * Record.getDescriptiveName(me) // "Person"
2785 * ```
2786 */
2787 function getDescriptiveName(record: Record<any>): string;
2788
2789 /**
2790 * A Record.Factory is created by the `Record()` function. Record instances
2791 * are created by passing it some of the accepted values for that Record
2792 * type:
2793 *
2794 * <!-- runkit:activate
2795 * { "preamble": "const { Record } = require('immutable')" }
2796 * -->
2797 * ```js
2798 * // makePerson is a Record Factory function
2799 * const makePerson = Record({ name: null, favoriteColor: 'unknown' });
2800 *
2801 * // alan is a Record instance
2802 * const alan = makePerson({ name: 'Alan' });
2803 * ```
2804 *
2805 * Note that Record Factories return `Record<TProps> & Readonly<TProps>`,
2806 * this allows use of both the Record instance API, and direct property
2807 * access on the resulting instances:
2808 *
2809 * <!-- runkit:activate
2810 * { "preamble": "const { Record } = require('immutable');const makePerson = Record({ name: null, favoriteColor: 'unknown' });const alan = makePerson({ name: 'Alan' });" }
2811 * -->
2812 * ```js
2813 * // Use the Record API
2814 * console.log('Record API: ' + alan.get('name'))
2815 *
2816 * // Or direct property access (Readonly)
2817 * console.log('property access: ' + alan.name)
2818 * ```
2819 *
2820 * **Flow Typing Records:**
2821 *
2822 * Use the `RecordFactory<TProps>` Flow type to get high quality type checking of
2823 * Records:
2824 *
2825 * ```js
2826 * import type { RecordFactory, RecordOf } from 'immutable';
2827 *
2828 * // Use RecordFactory<TProps> for defining new Record factory functions.
2829 * type PersonProps = { name: ?string, favoriteColor: string };
2830 * const makePerson: RecordFactory<PersonProps> = Record({ name: null, favoriteColor: 'unknown' });
2831 *
2832 * // Use RecordOf<T> for defining new instances of that Record.
2833 * type Person = RecordOf<PersonProps>;
2834 * const alan: Person = makePerson({ name: 'Alan' });
2835 * ```
2836 */
2837 namespace Factory {}
2838
2839 interface Factory<TProps extends object> {
2840 (values?: Partial<TProps> | Iterable<[string, unknown]>): Record<TProps> &
2841 Readonly<TProps>;
2842 new (
2843 values?: Partial<TProps> | Iterable<[string, unknown]>
2844 ): Record<TProps> & Readonly<TProps>;
2845
2846 /**
2847 * The name provided to `Record(values, name)` can be accessed with
2848 * `displayName`.
2849 */
2850 displayName: string;
2851 }
2852
2853 function Factory<TProps extends object>(
2854 values?: Partial<TProps> | Iterable<[string, unknown]>
2855 ): Record<TProps> & Readonly<TProps>;
2856 }
2857
2858 /**
2859 * Unlike other types in Immutable.js, the `Record()` function creates a new
2860 * Record Factory, which is a function that creates Record instances.
2861 *
2862 * See above for examples of using `Record()`.
2863 *
2864 * Note: `Record` is a factory function and not a class, and does not use the
2865 * `new` keyword during construction.
2866 */
2867 function Record<TProps extends object>(
2868 defaultValues: TProps,
2869 name?: string
2870 ): Record.Factory<TProps>;
2871
2872 interface Record<TProps extends object> {
2873 // Reading values
2874
2875 has(key: string): key is keyof TProps & string;
2876
2877 /**
2878 * Returns the value associated with the provided key, which may be the
2879 * default value defined when creating the Record factory function.
2880 *
2881 * If the requested key is not defined by this Record type, then
2882 * notSetValue will be returned if provided. Note that this scenario would
2883 * produce an error when using Flow or TypeScript.
2884 */
2885 get<K extends keyof TProps>(key: K, notSetValue?: unknown): TProps[K];
2886 get<T>(key: string, notSetValue: T): T;
2887
2888 // Reading deep values
2889
2890 hasIn(keyPath: Iterable<unknown>): boolean;
2891 getIn(keyPath: Iterable<unknown>): unknown;
2892
2893 // Value equality
2894
2895 equals(other: unknown): boolean;
2896 hashCode(): number;
2897
2898 // Persistent changes
2899
2900 set<K extends keyof TProps>(key: K, value: TProps[K]): this;
2901 update<K extends keyof TProps>(
2902 key: K,
2903 updater: (value: TProps[K]) => TProps[K]
2904 ): this;
2905 merge(
2906 ...collections: Array<Partial<TProps> | Iterable<[string, unknown]>>
2907 ): this;
2908 mergeDeep(
2909 ...collections: Array<Partial<TProps> | Iterable<[string, unknown]>>
2910 ): this;
2911
2912 mergeWith(
2913 merger: (oldVal: unknown, newVal: unknown, key: keyof TProps) => unknown,
2914 ...collections: Array<Partial<TProps> | Iterable<[string, unknown]>>
2915 ): this;
2916 mergeDeepWith(
2917 merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown,
2918 ...collections: Array<Partial<TProps> | Iterable<[string, unknown]>>
2919 ): this;
2920
2921 /**
2922 * Returns a new instance of this Record type with the value for the
2923 * specific key set to its default value.
2924 *
2925 * @alias remove
2926 */
2927 delete<K extends keyof TProps>(key: K): this;
2928 remove<K extends keyof TProps>(key: K): this;
2929
2930 /**
2931 * Returns a new instance of this Record type with all values set
2932 * to their default values.
2933 */
2934 clear(): this;
2935
2936 // Deep persistent changes
2937
2938 setIn(keyPath: Iterable<unknown>, value: unknown): this;
2939 updateIn(
2940 keyPath: Iterable<unknown>,
2941 updater: (value: unknown) => unknown
2942 ): this;
2943 mergeIn(keyPath: Iterable<unknown>, ...collections: Array<unknown>): this;
2944 mergeDeepIn(
2945 keyPath: Iterable<unknown>,
2946 ...collections: Array<unknown>
2947 ): this;
2948
2949 /**
2950 * @alias removeIn
2951 */
2952 deleteIn(keyPath: Iterable<unknown>): this;
2953 removeIn(keyPath: Iterable<unknown>): this;
2954
2955 // Conversion to JavaScript types
2956
2957 /**
2958 * Deeply converts this Record to equivalent native JavaScript Object.
2959 *
2960 * Note: This method may not be overridden. Objects with custom
2961 * serialization to plain JS may override toJSON() instead.
2962 */
2963 toJS(): DeepCopy<TProps>;
2964
2965 /**
2966 * Shallowly converts this Record to equivalent native JavaScript Object.
2967 */
2968 toJSON(): TProps;
2969
2970 /**
2971 * Shallowly converts this Record to equivalent JavaScript Object.
2972 */
2973 toObject(): TProps;
2974
2975 // Transient changes
2976
2977 /**
2978 * Note: Not all methods can be used on a mutable collection or within
2979 * `withMutations`! Only `set` may be used mutatively.
2980 *
2981 * @see `Map#withMutations`
2982 */
2983 withMutations(mutator: (mutable: this) => unknown): this;
2984
2985 /**
2986 * @see `Map#asMutable`
2987 */
2988 asMutable(): this;
2989
2990 /**
2991 * @see `Map#wasAltered`
2992 */
2993 wasAltered(): boolean;
2994
2995 /**
2996 * @see `Map#asImmutable`
2997 */
2998 asImmutable(): this;
2999
3000 // Sequence algorithms
3001
3002 toSeq(): Seq.Keyed<keyof TProps, TProps[keyof TProps]>;
3003
3004 [Symbol.iterator](): IterableIterator<[keyof TProps, TProps[keyof TProps]]>;
3005 }
3006
3007 /**
3008 * RecordOf<T> is used in TypeScript to define interfaces expecting an
3009 * instance of record with type T.
3010 *
3011 * This is equivalent to an instance of a record created by a Record Factory.
3012 */
3013 type RecordOf<TProps extends object> = Record<TProps> & Readonly<TProps>;
3014
3015 /**
3016 * `Seq` describes a lazy operation, allowing them to efficiently chain
3017 * use of all the higher-order collection methods (such as `map` and `filter`)
3018 * by not creating intermediate collections.
3019 *
3020 * **Seq is immutable** — Once a Seq is created, it cannot be
3021 * changed, appended to, rearranged or otherwise modified. Instead, any
3022 * mutative method called on a `Seq` will return a new `Seq`.
3023 *
3024 * **Seq is lazy** — `Seq` does as little work as necessary to respond to any
3025 * method call. Values are often created during iteration, including implicit
3026 * iteration when reducing or converting to a concrete data structure such as
3027 * a `List` or JavaScript `Array`.
3028 *
3029 * For example, the following performs no work, because the resulting
3030 * `Seq`'s values are never iterated:
3031 *
3032 * ```js
3033 * const { Seq } = require('immutable')
3034 * const oddSquares = Seq([ 1, 2, 3, 4, 5, 6, 7, 8 ])
3035 * .filter(x => x % 2 !== 0)
3036 * .map(x => x * x)
3037 * ```
3038 *
3039 * Once the `Seq` is used, it performs only the work necessary. In this
3040 * example, no intermediate arrays are ever created, filter is called three
3041 * times, and map is only called once:
3042 *
3043 * ```js
3044 * oddSquares.get(1); // 9
3045 * ```
3046 *
3047 * Any collection can be converted to a lazy Seq with `Seq()`.
3048 *
3049 * <!-- runkit:activate -->
3050 * ```js
3051 * const { Map } = require('immutable')
3052 * const map = Map({ a: 1, b: 2, c: 3 })
3053 * const lazySeq = Seq(map)
3054 * ```
3055 *
3056 * `Seq` allows for the efficient chaining of operations, allowing for the
3057 * expression of logic that can otherwise be very tedious:
3058 *
3059 * ```js
3060 * lazySeq
3061 * .flip()
3062 * .map(key => key.toUpperCase())
3063 * .flip()
3064 * // Seq { A: 1, B: 1, C: 1 }
3065 * ```
3066 *
3067 * As well as expressing logic that would otherwise seem memory or time
3068 * limited, for example `Range` is a special kind of Lazy sequence.
3069 *
3070 * <!-- runkit:activate -->
3071 * ```js
3072 * const { Range } = require('immutable')
3073 * Range(1, Infinity)
3074 * .skip(1000)
3075 * .map(n => -n)
3076 * .filter(n => n % 2 === 0)
3077 * .take(2)
3078 * .reduce((r, n) => r * n, 1)
3079 * // 1006008
3080 * ```
3081 *
3082 * Seq is often used to provide a rich collection API to JavaScript Object.
3083 *
3084 * ```js
3085 * Seq({ x: 0, y: 1, z: 2 }).map(v => v * 2).toObject();
3086 * // { x: 0, y: 2, z: 4 }
3087 * ```
3088 */
3089
3090 namespace Seq {
3091 /**
3092 * True if `maybeSeq` is a Seq, it is not backed by a concrete
3093 * structure such as Map, List, or Set.
3094 */
3095 function isSeq(
3096 maybeSeq: unknown
3097 ): maybeSeq is
3098 | Seq.Indexed<unknown>
3099 | Seq.Keyed<unknown, unknown>
3100 | Seq.Set<unknown>;
3101
3102 /**
3103 * `Seq` which represents key-value pairs.
3104 */
3105 namespace Keyed {}
3106
3107 /**
3108 * Always returns a Seq.Keyed, if input is not keyed, expects an
3109 * collection of [K, V] tuples.
3110 *
3111 * Note: `Seq.Keyed` is a conversion function and not a class, and does not
3112 * use the `new` keyword during construction.
3113 */
3114 function Keyed<K, V>(collection?: Iterable<[K, V]>): Seq.Keyed<K, V>;
3115 function Keyed<V>(obj: { [key: string]: V }): Seq.Keyed<string, V>;
3116
3117 interface Keyed<K, V> extends Seq<K, V>, Collection.Keyed<K, V> {
3118 /**
3119 * Deeply converts this Keyed Seq to equivalent native JavaScript Object.
3120 *
3121 * Converts keys to Strings.
3122 */
3123 toJS(): { [key in string | number | symbol]: DeepCopy<V> };
3124
3125 /**
3126 * Shallowly converts this Keyed Seq to equivalent native JavaScript Object.
3127 *
3128 * Converts keys to Strings.
3129 */
3130 toJSON(): { [key in string | number | symbol]: V };
3131
3132 /**
3133 * Shallowly converts this collection to an Array.
3134 */
3135 toArray(): Array<[K, V]>;
3136
3137 /**
3138 * Returns itself
3139 */
3140 toSeq(): this;
3141
3142 /**
3143 * Returns a new Seq with other collections concatenated to this one.
3144 *
3145 * All entries will be present in the resulting Seq, even if they
3146 * have the same key.
3147 */
3148 concat<KC, VC>(
3149 ...collections: Array<Iterable<[KC, VC]>>
3150 ): Seq.Keyed<K | KC, V | VC>;
3151 concat<C>(
3152 ...collections: Array<{ [key: string]: C }>
3153 ): Seq.Keyed<K | string, V | C>;
3154
3155 /**
3156 * Returns a new Seq.Keyed with values passed through a
3157 * `mapper` function.
3158 *
3159 * ```js
3160 * const { Seq } = require('immutable')
3161 * Seq.Keyed({ a: 1, b: 2 }).map(x => 10 * x)
3162 * // Seq { "a": 10, "b": 20 }
3163 * ```
3164 *
3165 * Note: `map()` always returns a new instance, even if it produced the
3166 * same value at every step.
3167 */
3168 map<M>(
3169 mapper: (value: V, key: K, iter: this) => M,
3170 context?: unknown
3171 ): Seq.Keyed<K, M>;
3172
3173 /**
3174 * @see Collection.Keyed.mapKeys
3175 */
3176 mapKeys<M>(
3177 mapper: (key: K, value: V, iter: this) => M,
3178 context?: unknown
3179 ): Seq.Keyed<M, V>;
3180
3181 /**
3182 * @see Collection.Keyed.mapEntries
3183 */
3184 mapEntries<KM, VM>(
3185 mapper: (
3186 entry: [K, V],
3187 index: number,
3188 iter: this
3189 ) => [KM, VM] | undefined,
3190 context?: unknown
3191 ): Seq.Keyed<KM, VM>;
3192
3193 /**
3194 * Flat-maps the Seq, returning a Seq of the same type.
3195 *
3196 * Similar to `seq.map(...).flatten(true)`.
3197 */
3198 flatMap<KM, VM>(
3199 mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
3200 context?: unknown
3201 ): Seq.Keyed<KM, VM>;
3202
3203 /**
3204 * Returns a new Seq with only the entries for which the `predicate`
3205 * function returns true.
3206 *
3207 * Note: `filter()` always returns a new instance, even if it results in
3208 * not filtering out any values.
3209 */
3210 filter<F extends V>(
3211 predicate: (value: V, key: K, iter: this) => value is F,
3212 context?: unknown
3213 ): Seq.Keyed<K, F>;
3214 filter(
3215 predicate: (value: V, key: K, iter: this) => unknown,
3216 context?: unknown
3217 ): this;
3218
3219 /**
3220 * Returns a new keyed Seq with the values for which the `predicate`
3221 * function returns false and another for which is returns true.
3222 */
3223 partition<F extends V, C>(
3224 predicate: (this: C, value: V, key: K, iter: this) => value is F,
3225 context?: C
3226 ): [Seq.Keyed<K, V>, Seq.Keyed<K, F>];
3227 partition<C>(
3228 predicate: (this: C, value: V, key: K, iter: this) => unknown,
3229 context?: C
3230 ): [this, this];
3231
3232 /**
3233 * @see Collection.Keyed.flip
3234 */
3235 flip(): Seq.Keyed<V, K>;
3236
3237 [Symbol.iterator](): IterableIterator<[K, V]>;
3238 }
3239
3240 /**
3241 * `Seq` which represents an ordered indexed list of values.
3242 */
3243 namespace Indexed {
3244 /**
3245 * Provides an Seq.Indexed of the values provided.
3246 */
3247 function of<T>(...values: Array<T>): Seq.Indexed<T>;
3248 }
3249
3250 /**
3251 * Always returns Seq.Indexed, discarding associated keys and
3252 * supplying incrementing indices.
3253 *
3254 * Note: `Seq.Indexed` is a conversion function and not a class, and does
3255 * not use the `new` keyword during construction.
3256 */
3257 function Indexed<T>(
3258 collection?: Iterable<T> | ArrayLike<T>
3259 ): Seq.Indexed<T>;
3260
3261 interface Indexed<T> extends Seq<number, T>, Collection.Indexed<T> {
3262 /**
3263 * Deeply converts this Indexed Seq to equivalent native JavaScript Array.
3264 */
3265 toJS(): Array<DeepCopy<T>>;
3266
3267 /**
3268 * Shallowly converts this Indexed Seq to equivalent native JavaScript Array.
3269 */
3270 toJSON(): Array<T>;
3271
3272 /**
3273 * Shallowly converts this collection to an Array.
3274 */
3275 toArray(): Array<T>;
3276
3277 /**
3278 * Returns itself
3279 */
3280 toSeq(): this;
3281
3282 /**
3283 * Returns a new Seq with other collections concatenated to this one.
3284 */
3285 concat<C>(
3286 ...valuesOrCollections: Array<Iterable<C> | C>
3287 ): Seq.Indexed<T | C>;
3288
3289 /**
3290 * Returns a new Seq.Indexed with values passed through a
3291 * `mapper` function.
3292 *
3293 * ```js
3294 * const { Seq } = require('immutable')
3295 * Seq.Indexed([ 1, 2 ]).map(x => 10 * x)
3296 * // Seq [ 10, 20 ]
3297 * ```
3298 *
3299 * Note: `map()` always returns a new instance, even if it produced the
3300 * same value at every step.
3301 */
3302 map<M>(
3303 mapper: (value: T, key: number, iter: this) => M,
3304 context?: unknown
3305 ): Seq.Indexed<M>;
3306
3307 /**
3308 * Flat-maps the Seq, returning a a Seq of the same type.
3309 *
3310 * Similar to `seq.map(...).flatten(true)`.
3311 */
3312 flatMap<M>(
3313 mapper: (value: T, key: number, iter: this) => Iterable<M>,
3314 context?: unknown
3315 ): Seq.Indexed<M>;
3316
3317 /**
3318 * Returns a new Seq with only the values for which the `predicate`
3319 * function returns true.
3320 *
3321 * Note: `filter()` always returns a new instance, even if it results in
3322 * not filtering out any values.
3323 */
3324 filter<F extends T>(
3325 predicate: (value: T, index: number, iter: this) => value is F,
3326 context?: unknown
3327 ): Seq.Indexed<F>;
3328 filter(
3329 predicate: (value: T, index: number, iter: this) => unknown,
3330 context?: unknown
3331 ): this;
3332
3333 /**
3334 * Returns a new indexed Seq with the values for which the `predicate`
3335 * function returns false and another for which is returns true.
3336 */
3337 partition<F extends T, C>(
3338 predicate: (this: C, value: T, index: number, iter: this) => value is F,
3339 context?: C
3340 ): [Seq.Indexed<T>, Seq.Indexed<F>];
3341 partition<C>(
3342 predicate: (this: C, value: T, index: number, iter: this) => unknown,
3343 context?: C
3344 ): [this, this];
3345
3346 /**
3347 * Returns a Seq "zipped" with the provided collections.
3348 *
3349 * Like `zipWith`, but using the default `zipper`: creating an `Array`.
3350 *
3351 * ```js
3352 * const a = Seq([ 1, 2, 3 ]);
3353 * const b = Seq([ 4, 5, 6 ]);
3354 * const c = a.zip(b); // Seq [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
3355 * ```
3356 */
3357 zip<U>(other: Collection<unknown, U>): Seq.Indexed<[T, U]>;
3358 zip<U, V>(
3359 other: Collection<unknown, U>,
3360 other2: Collection<unknown, V>
3361 ): Seq.Indexed<[T, U, V]>;
3362 zip(
3363 ...collections: Array<Collection<unknown, unknown>>
3364 ): Seq.Indexed<unknown>;
3365
3366 /**
3367 * Returns a Seq "zipped" with the provided collections.
3368 *
3369 * Unlike `zip`, `zipAll` continues zipping until the longest collection is
3370 * exhausted. Missing values from shorter collections are filled with `undefined`.
3371 *
3372 * ```js
3373 * const a = Seq([ 1, 2 ]);
3374 * const b = Seq([ 3, 4, 5 ]);
3375 * const c = a.zipAll(b); // Seq [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ]
3376 * ```
3377 */
3378 zipAll<U>(other: Collection<unknown, U>): Seq.Indexed<[T, U]>;
3379 zipAll<U, V>(
3380 other: Collection<unknown, U>,
3381 other2: Collection<unknown, V>
3382 ): Seq.Indexed<[T, U, V]>;
3383 zipAll(
3384 ...collections: Array<Collection<unknown, unknown>>
3385 ): Seq.Indexed<unknown>;
3386
3387 /**
3388 * Returns a Seq "zipped" with the provided collections by using a
3389 * custom `zipper` function.
3390 *
3391 * ```js
3392 * const a = Seq([ 1, 2, 3 ]);
3393 * const b = Seq([ 4, 5, 6 ]);
3394 * const c = a.zipWith((a, b) => a + b, b);
3395 * // Seq [ 5, 7, 9 ]
3396 * ```
3397 */
3398 zipWith<U, Z>(
3399 zipper: (value: T, otherValue: U) => Z,
3400 otherCollection: Collection<unknown, U>
3401 ): Seq.Indexed<Z>;
3402 zipWith<U, V, Z>(
3403 zipper: (value: T, otherValue: U, thirdValue: V) => Z,
3404 otherCollection: Collection<unknown, U>,
3405 thirdCollection: Collection<unknown, V>
3406 ): Seq.Indexed<Z>;
3407 zipWith<Z>(
3408 zipper: (...values: Array<unknown>) => Z,
3409 ...collections: Array<Collection<unknown, unknown>>
3410 ): Seq.Indexed<Z>;
3411
3412 [Symbol.iterator](): IterableIterator<T>;
3413 }
3414
3415 /**
3416 * `Seq` which represents a set of values.
3417 *
3418 * Because `Seq` are often lazy, `Seq.Set` does not provide the same guarantee
3419 * of value uniqueness as the concrete `Set`.
3420 */
3421 namespace Set {
3422 /**
3423 * Returns a Seq.Set of the provided values
3424 */
3425 function of<T>(...values: Array<T>): Seq.Set<T>;
3426 }
3427
3428 /**
3429 * Always returns a Seq.Set, discarding associated indices or keys.
3430 *
3431 * Note: `Seq.Set` is a conversion function and not a class, and does not
3432 * use the `new` keyword during construction.
3433 */
3434 function Set<T>(collection?: Iterable<T> | ArrayLike<T>): Seq.Set<T>;
3435
3436 interface Set<T> extends Seq<T, T>, Collection.Set<T> {
3437 /**
3438 * Deeply converts this Set Seq to equivalent native JavaScript Array.
3439 */
3440 toJS(): Array<DeepCopy<T>>;
3441
3442 /**
3443 * Shallowly converts this Set Seq to equivalent native JavaScript Array.
3444 */
3445 toJSON(): Array<T>;
3446
3447 /**
3448 * Shallowly converts this collection to an Array.
3449 */
3450 toArray(): Array<T>;
3451
3452 /**
3453 * Returns itself
3454 */
3455 toSeq(): this;
3456
3457 /**
3458 * Returns a new Seq with other collections concatenated to this one.
3459 *
3460 * All entries will be present in the resulting Seq, even if they
3461 * are duplicates.
3462 */
3463 concat<U>(...collections: Array<Iterable<U>>): Seq.Set<T | U>;
3464
3465 /**
3466 * Returns a new Seq.Set with values passed through a
3467 * `mapper` function.
3468 *
3469 * ```js
3470 * Seq.Set([ 1, 2 ]).map(x => 10 * x)
3471 * // Seq { 10, 20 }
3472 * ```
3473 *
3474 * Note: `map()` always returns a new instance, even if it produced the
3475 * same value at every step.
3476 */
3477 map<M>(
3478 mapper: (value: T, key: T, iter: this) => M,
3479 context?: unknown
3480 ): Seq.Set<M>;
3481
3482 /**
3483 * Flat-maps the Seq, returning a Seq of the same type.
3484 *
3485 * Similar to `seq.map(...).flatten(true)`.
3486 */
3487 flatMap<M>(
3488 mapper: (value: T, key: T, iter: this) => Iterable<M>,
3489 context?: unknown
3490 ): Seq.Set<M>;
3491
3492 /**
3493 * Returns a new Seq with only the values for which the `predicate`
3494 * function returns true.
3495 *
3496 * Note: `filter()` always returns a new instance, even if it results in
3497 * not filtering out any values.
3498 */
3499 filter<F extends T>(
3500 predicate: (value: T, key: T, iter: this) => value is F,
3501 context?: unknown
3502 ): Seq.Set<F>;
3503 filter(
3504 predicate: (value: T, key: T, iter: this) => unknown,
3505 context?: unknown
3506 ): this;
3507
3508 /**
3509 * Returns a new set Seq with the values for which the `predicate`
3510 * function returns false and another for which is returns true.
3511 */
3512 partition<F extends T, C>(
3513 predicate: (this: C, value: T, key: T, iter: this) => value is F,
3514 context?: C
3515 ): [Seq.Set<T>, Seq.Set<F>];
3516 partition<C>(
3517 predicate: (this: C, value: T, key: T, iter: this) => unknown,
3518 context?: C
3519 ): [this, this];
3520
3521 [Symbol.iterator](): IterableIterator<T>;
3522 }
3523 }
3524
3525 /**
3526 * Creates a Seq.
3527 *
3528 * Returns a particular kind of `Seq` based on the input.
3529 *
3530 * * If a `Seq`, that same `Seq`.
3531 * * If an `Collection`, a `Seq` of the same kind (Keyed, Indexed, or Set).
3532 * * If an Array-like, an `Seq.Indexed`.
3533 * * If an Iterable Object, an `Seq.Indexed`.
3534 * * If an Object, a `Seq.Keyed`.
3535 *
3536 * Note: An Iterator itself will be treated as an object, becoming a `Seq.Keyed`,
3537 * which is usually not what you want. You should turn your Iterator Object into
3538 * an iterable object by defining a Symbol.iterator (or @@iterator) method which
3539 * returns `this`.
3540 *
3541 * Note: `Seq` is a conversion function and not a class, and does not use the
3542 * `new` keyword during construction.
3543 */
3544 function Seq<S extends Seq<unknown, unknown>>(seq: S): S;
3545 function Seq<K, V>(collection: Collection.Keyed<K, V>): Seq.Keyed<K, V>;
3546 function Seq<T>(collection: Collection.Set<T>): Seq.Set<T>;
3547 function Seq<T>(
3548 collection: Collection.Indexed<T> | Iterable<T> | ArrayLike<T>
3549 ): Seq.Indexed<T>;
3550 function Seq<V>(obj: { [key: string]: V }): Seq.Keyed<string, V>;
3551 function Seq<K = unknown, V = unknown>(): Seq<K, V>;
3552
3553 interface Seq<K, V> extends Collection<K, V> {
3554 /**
3555 * Some Seqs can describe their size lazily. When this is the case,
3556 * size will be an integer. Otherwise it will be undefined.
3557 *
3558 * For example, Seqs returned from `map()` or `reverse()`
3559 * preserve the size of the original `Seq` while `filter()` does not.
3560 *
3561 * Note: `Range`, `Repeat` and `Seq`s made from `Array`s and `Object`s will
3562 * always have a size.
3563 */
3564 readonly size: number | undefined;
3565
3566 // Force evaluation
3567
3568 /**
3569 * Because Sequences are lazy and designed to be chained together, they do
3570 * not cache their results. For example, this map function is called a total
3571 * of 6 times, as each `join` iterates the Seq of three values.
3572 *
3573 * var squares = Seq([ 1, 2, 3 ]).map(x => x * x)
3574 * squares.join() + squares.join()
3575 *
3576 * If you know a `Seq` will be used multiple times, it may be more
3577 * efficient to first cache it in memory. Here, the map function is called
3578 * only 3 times.
3579 *
3580 * var squares = Seq([ 1, 2, 3 ]).map(x => x * x).cacheResult()
3581 * squares.join() + squares.join()
3582 *
3583 * Use this method judiciously, as it must fully evaluate a Seq which can be
3584 * a burden on memory and possibly performance.
3585 *
3586 * Note: after calling `cacheResult`, a Seq will always have a `size`.
3587 */
3588 cacheResult(): this;
3589
3590 // Sequence algorithms
3591
3592 /**
3593 * Returns a new Seq with values passed through a
3594 * `mapper` function.
3595 *
3596 * ```js
3597 * const { Seq } = require('immutable')
3598 * Seq([ 1, 2 ]).map(x => 10 * x)
3599 * // Seq [ 10, 20 ]
3600 * ```
3601 *
3602 * Note: `map()` always returns a new instance, even if it produced the same
3603 * value at every step.
3604 */
3605 map<M>(
3606 mapper: (value: V, key: K, iter: this) => M,
3607 context?: unknown
3608 ): Seq<K, M>;
3609
3610 /**
3611 * Returns a new Seq with values passed through a
3612 * `mapper` function.
3613 *
3614 * ```js
3615 * const { Seq } = require('immutable')
3616 * Seq([ 1, 2 ]).map(x => 10 * x)
3617 * // Seq [ 10, 20 ]
3618 * ```
3619 *
3620 * Note: `map()` always returns a new instance, even if it produced the same
3621 * value at every step.
3622 * Note: used only for sets.
3623 */
3624 map<M>(
3625 mapper: (value: V, key: K, iter: this) => M,
3626 context?: unknown
3627 ): Seq<M, M>;
3628
3629 /**
3630 * Flat-maps the Seq, returning a Seq of the same type.
3631 *
3632 * Similar to `seq.map(...).flatten(true)`.
3633 */
3634 flatMap<M>(
3635 mapper: (value: V, key: K, iter: this) => Iterable<M>,
3636 context?: unknown
3637 ): Seq<K, M>;
3638
3639 /**
3640 * Flat-maps the Seq, returning a Seq of the same type.
3641 *
3642 * Similar to `seq.map(...).flatten(true)`.
3643 * Note: Used only for sets.
3644 */
3645 flatMap<M>(
3646 mapper: (value: V, key: K, iter: this) => Iterable<M>,
3647 context?: unknown
3648 ): Seq<M, M>;
3649
3650 /**
3651 * Returns a new Seq with only the values for which the `predicate`
3652 * function returns true.
3653 *
3654 * Note: `filter()` always returns a new instance, even if it results in
3655 * not filtering out any values.
3656 */
3657 filter<F extends V>(
3658 predicate: (value: V, key: K, iter: this) => value is F,
3659 context?: unknown
3660 ): Seq<K, F>;
3661 filter(
3662 predicate: (value: V, key: K, iter: this) => unknown,
3663 context?: unknown
3664 ): this;
3665
3666 /**
3667 * Returns a new Seq with the values for which the `predicate` function
3668 * returns false and another for which is returns true.
3669 */
3670 partition<F extends V, C>(
3671 predicate: (this: C, value: V, key: K, iter: this) => value is F,
3672 context?: C
3673 ): [Seq<K, V>, Seq<K, F>];
3674 partition<C>(
3675 predicate: (this: C, value: V, key: K, iter: this) => unknown,
3676 context?: C
3677 ): [this, this];
3678 }
3679
3680 /**
3681 * The `Collection` is a set of (key, value) entries which can be iterated, and
3682 * is the base class for all collections in `immutable`, allowing them to
3683 * make use of all the Collection methods (such as `map` and `filter`).
3684 *
3685 * Note: A collection is always iterated in the same order, however that order
3686 * may not always be well defined, as is the case for the `Map` and `Set`.
3687 *
3688 * Collection is the abstract base class for concrete data structures. It
3689 * cannot be constructed directly.
3690 *
3691 * Implementations should extend one of the subclasses, `Collection.Keyed`,
3692 * `Collection.Indexed`, or `Collection.Set`.
3693 */
3694 namespace Collection {
3695 /**
3696 * Keyed Collections have discrete keys tied to each value.
3697 *
3698 * When iterating `Collection.Keyed`, each iteration will yield a `[K, V]`
3699 * tuple, in other words, `Collection#entries` is the default iterator for
3700 * Keyed Collections.
3701 */
3702 namespace Keyed {}
3703
3704 /**
3705 * Creates a Collection.Keyed
3706 *
3707 * Similar to `Collection()`, however it expects collection-likes of [K, V]
3708 * tuples if not constructed from a Collection.Keyed or JS Object.
3709 *
3710 * Note: `Collection.Keyed` is a conversion function and not a class, and
3711 * does not use the `new` keyword during construction.
3712 */
3713 function Keyed<K, V>(collection?: Iterable<[K, V]>): Collection.Keyed<K, V>;
3714 function Keyed<V>(obj: { [key: string]: V }): Collection.Keyed<string, V>;
3715
3716 interface Keyed<K, V> extends Collection<K, V> {
3717 /**
3718 * Deeply converts this Keyed collection to equivalent native JavaScript Object.
3719 *
3720 * Converts keys to Strings.
3721 */
3722 toJS(): { [key in string | number | symbol]: DeepCopy<V> };
3723
3724 /**
3725 * Shallowly converts this Keyed collection to equivalent native JavaScript Object.
3726 *
3727 * Converts keys to Strings.
3728 */
3729 toJSON(): { [key in string | number | symbol]: V };
3730
3731 /**
3732 * Shallowly converts this collection to an Array.
3733 */
3734 toArray(): Array<[K, V]>;
3735
3736 /**
3737 * Returns Seq.Keyed.
3738 * @override
3739 */
3740 toSeq(): Seq.Keyed<K, V>;
3741
3742 // Sequence functions
3743
3744 /**
3745 * Returns a new Collection.Keyed of the same type where the keys and values
3746 * have been flipped.
3747 *
3748 * <!-- runkit:activate -->
3749 * ```js
3750 * const { Map } = require('immutable')
3751 * Map({ a: 'z', b: 'y' }).flip()
3752 * // Map { "z": "a", "y": "b" }
3753 * ```
3754 */
3755 flip(): Collection.Keyed<V, K>;
3756
3757 /**
3758 * Returns a new Collection with other collections concatenated to this one.
3759 */
3760 concat<KC, VC>(
3761 ...collections: Array<Iterable<[KC, VC]>>
3762 ): Collection.Keyed<K | KC, V | VC>;
3763 concat<C>(
3764 ...collections: Array<{ [key: string]: C }>
3765 ): Collection.Keyed<K | string, V | C>;
3766
3767 /**
3768 * Returns a new Collection.Keyed with values passed through a
3769 * `mapper` function.
3770 *
3771 * ```js
3772 * const { Collection } = require('immutable')
3773 * Collection.Keyed({ a: 1, b: 2 }).map(x => 10 * x)
3774 * // Seq { "a": 10, "b": 20 }
3775 * ```
3776 *
3777 * Note: `map()` always returns a new instance, even if it produced the
3778 * same value at every step.
3779 */
3780 map<M>(
3781 mapper: (value: V, key: K, iter: this) => M,
3782 context?: unknown
3783 ): Collection.Keyed<K, M>;
3784
3785 /**
3786 * Returns a new Collection.Keyed of the same type with keys passed through
3787 * a `mapper` function.
3788 *
3789 * <!-- runkit:activate -->
3790 * ```js
3791 * const { Map } = require('immutable')
3792 * Map({ a: 1, b: 2 }).mapKeys(x => x.toUpperCase())
3793 * // Map { "A": 1, "B": 2 }
3794 * ```
3795 *
3796 * Note: `mapKeys()` always returns a new instance, even if it produced
3797 * the same key at every step.
3798 */
3799 mapKeys<M>(
3800 mapper: (key: K, value: V, iter: this) => M,
3801 context?: unknown
3802 ): Collection.Keyed<M, V>;
3803
3804 /**
3805 * Returns a new Collection.Keyed of the same type with entries
3806 * ([key, value] tuples) passed through a `mapper` function.
3807 *
3808 * <!-- runkit:activate -->
3809 * ```js
3810 * const { Map } = require('immutable')
3811 * Map({ a: 1, b: 2 })
3812 * .mapEntries(([ k, v ]) => [ k.toUpperCase(), v * 2 ])
3813 * // Map { "A": 2, "B": 4 }
3814 * ```
3815 *
3816 * Note: `mapEntries()` always returns a new instance, even if it produced
3817 * the same entry at every step.
3818 *
3819 * If the mapper function returns `undefined`, then the entry will be filtered
3820 */
3821 mapEntries<KM, VM>(
3822 mapper: (
3823 entry: [K, V],
3824 index: number,
3825 iter: this
3826 ) => [KM, VM] | undefined,
3827 context?: unknown
3828 ): Collection.Keyed<KM, VM>;
3829
3830 /**
3831 * Flat-maps the Collection, returning a Collection of the same type.
3832 *
3833 * Similar to `collection.map(...).flatten(true)`.
3834 */
3835 flatMap<KM, VM>(
3836 mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
3837 context?: unknown
3838 ): Collection.Keyed<KM, VM>;
3839
3840 /**
3841 * Returns a new Collection with only the values for which the `predicate`
3842 * function returns true.
3843 *
3844 * Note: `filter()` always returns a new instance, even if it results in
3845 * not filtering out any values.
3846 */
3847 filter<F extends V>(
3848 predicate: (value: V, key: K, iter: this) => value is F,
3849 context?: unknown
3850 ): Collection.Keyed<K, F>;
3851 filter(
3852 predicate: (value: V, key: K, iter: this) => unknown,
3853 context?: unknown
3854 ): this;
3855
3856 /**
3857 * Returns a new keyed Collection with the values for which the
3858 * `predicate` function returns false and another for which is returns
3859 * true.
3860 */
3861 partition<F extends V, C>(
3862 predicate: (this: C, value: V, key: K, iter: this) => value is F,
3863 context?: C
3864 ): [Collection.Keyed<K, V>, Collection.Keyed<K, F>];
3865 partition<C>(
3866 predicate: (this: C, value: V, key: K, iter: this) => unknown,
3867 context?: C
3868 ): [this, this];
3869
3870 [Symbol.iterator](): IterableIterator<[K, V]>;
3871 }
3872
3873 /**
3874 * Indexed Collections have incrementing numeric keys. They exhibit
3875 * slightly different behavior than `Collection.Keyed` for some methods in order
3876 * to better mirror the behavior of JavaScript's `Array`, and add methods
3877 * which do not make sense on non-indexed Collections such as `indexOf`.
3878 *
3879 * Unlike JavaScript arrays, `Collection.Indexed`s are always dense. "Unset"
3880 * indices and `undefined` indices are indistinguishable, and all indices from
3881 * 0 to `size` are visited when iterated.
3882 *
3883 * All Collection.Indexed methods return re-indexed Collections. In other words,
3884 * indices always start at 0 and increment until size. If you wish to
3885 * preserve indices, using them as keys, convert to a Collection.Keyed by
3886 * calling `toKeyedSeq`.
3887 */
3888 namespace Indexed {}
3889
3890 /**
3891 * Creates a new Collection.Indexed.
3892 *
3893 * Note: `Collection.Indexed` is a conversion function and not a class, and
3894 * does not use the `new` keyword during construction.
3895 */
3896 function Indexed<T>(
3897 collection?: Iterable<T> | ArrayLike<T>
3898 ): Collection.Indexed<T>;
3899
3900 interface Indexed<T> extends Collection<number, T> {
3901 /**
3902 * Deeply converts this Indexed collection to equivalent native JavaScript Array.
3903 */
3904 toJS(): Array<DeepCopy<T>>;
3905
3906 /**
3907 * Shallowly converts this Indexed collection to equivalent native JavaScript Array.
3908 */
3909 toJSON(): Array<T>;
3910
3911 /**
3912 * Shallowly converts this collection to an Array.
3913 */
3914 toArray(): Array<T>;
3915
3916 // Reading values
3917
3918 /**
3919 * Returns the value associated with the provided index, or notSetValue if
3920 * the index is beyond the bounds of the Collection.
3921 *
3922 * `index` may be a negative number, which indexes back from the end of the
3923 * Collection. `s.get(-1)` gets the last item in the Collection.
3924 */
3925 get<NSV>(index: number, notSetValue: NSV): T | NSV;
3926 get(index: number): T | undefined;
3927
3928 // Conversion to Seq
3929
3930 /**
3931 * Returns Seq.Indexed.
3932 * @override
3933 */
3934 toSeq(): Seq.Indexed<T>;
3935
3936 /**
3937 * If this is a collection of [key, value] entry tuples, it will return a
3938 * Seq.Keyed of those entries.
3939 */
3940 fromEntrySeq(): Seq.Keyed<unknown, unknown>;
3941
3942 // Combination
3943
3944 /**
3945 * Returns a Collection of the same type with `separator` between each item
3946 * in this Collection.
3947 */
3948 interpose(separator: T): this;
3949
3950 /**
3951 * Returns a Collection of the same type with the provided `collections`
3952 * interleaved into this collection.
3953 *
3954 * The resulting Collection includes the first item from each, then the
3955 * second from each, etc.
3956 *
3957 * <!-- runkit:activate
3958 * { "preamble": "require('immutable')"}
3959 * -->
3960 * ```js
3961 * const { List } = require('immutable')
3962 * List([ 1, 2, 3 ]).interleave(List([ 'A', 'B', 'C' ]))
3963 * // List [ 1, "A", 2, "B", 3, "C" ]
3964 * ```
3965 *
3966 * The shortest Collection stops interleave.
3967 *
3968 * <!-- runkit:activate
3969 * { "preamble": "const { List } = require('immutable')" }
3970 * -->
3971 * ```js
3972 * List([ 1, 2, 3 ]).interleave(
3973 * List([ 'A', 'B' ]),
3974 * List([ 'X', 'Y', 'Z' ])
3975 * )
3976 * // List [ 1, "A", "X", 2, "B", "Y" ]
3977 * ```
3978 *
3979 * Since `interleave()` re-indexes values, it produces a complete copy,
3980 * which has `O(N)` complexity.
3981 *
3982 * Note: `interleave` *cannot* be used in `withMutations`.
3983 */
3984 interleave(...collections: Array<Collection<unknown, T>>): this;
3985
3986 /**
3987 * Splice returns a new indexed Collection by replacing a region of this
3988 * Collection with new values. If values are not provided, it only skips the
3989 * region to be removed.
3990 *
3991 * `index` may be a negative number, which indexes back from the end of the
3992 * Collection. `s.splice(-2)` splices after the second to last item.
3993 *
3994 * <!-- runkit:activate -->
3995 * ```js
3996 * const { List } = require('immutable')
3997 * List([ 'a', 'b', 'c', 'd' ]).splice(1, 2, 'q', 'r', 's')
3998 * // List [ "a", "q", "r", "s", "d" ]
3999 * ```
4000 *
4001 * Since `splice()` re-indexes values, it produces a complete copy, which
4002 * has `O(N)` complexity.
4003 *
4004 * Note: `splice` *cannot* be used in `withMutations`.
4005 */
4006 splice(index: number, removeNum: number, ...values: Array<T>): this;
4007
4008 /**
4009 * Returns a Collection of the same type "zipped" with the provided
4010 * collections.
4011 *
4012 * Like `zipWith`, but using the default `zipper`: creating an `Array`.
4013 *
4014 *
4015 * <!-- runkit:activate
4016 * { "preamble": "const { List } = require('immutable')" }
4017 * -->
4018 * ```js
4019 * const a = List([ 1, 2, 3 ]);
4020 * const b = List([ 4, 5, 6 ]);
4021 * const c = a.zip(b); // List [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
4022 * ```
4023 */
4024 zip<U>(other: Collection<unknown, U>): Collection.Indexed<[T, U]>;
4025 zip<U, V>(
4026 other: Collection<unknown, U>,
4027 other2: Collection<unknown, V>
4028 ): Collection.Indexed<[T, U, V]>;
4029 zip(
4030 ...collections: Array<Collection<unknown, unknown>>
4031 ): Collection.Indexed<unknown>;
4032
4033 /**
4034 * Returns a Collection "zipped" with the provided collections.
4035 *
4036 * Unlike `zip`, `zipAll` continues zipping until the longest collection is
4037 * exhausted. Missing values from shorter collections are filled with `undefined`.
4038 *
4039 * ```js
4040 * const a = List([ 1, 2 ]);
4041 * const b = List([ 3, 4, 5 ]);
4042 * const c = a.zipAll(b); // List [ [ 1, 3 ], [ 2, 4 ], [ undefined, 5 ] ]
4043 * ```
4044 */
4045 zipAll<U>(other: Collection<unknown, U>): Collection.Indexed<[T, U]>;
4046 zipAll<U, V>(
4047 other: Collection<unknown, U>,
4048 other2: Collection<unknown, V>
4049 ): Collection.Indexed<[T, U, V]>;
4050 zipAll(
4051 ...collections: Array<Collection<unknown, unknown>>
4052 ): Collection.Indexed<unknown>;
4053
4054 /**
4055 * Returns a Collection of the same type "zipped" with the provided
4056 * collections by using a custom `zipper` function.
4057 *
4058 * <!-- runkit:activate
4059 * { "preamble": "const { List } = require('immutable')" }
4060 * -->
4061 * ```js
4062 * const a = List([ 1, 2, 3 ]);
4063 * const b = List([ 4, 5, 6 ]);
4064 * const c = a.zipWith((a, b) => a + b, b);
4065 * // List [ 5, 7, 9 ]
4066 * ```
4067 */
4068 zipWith<U, Z>(
4069 zipper: (value: T, otherValue: U) => Z,
4070 otherCollection: Collection<unknown, U>
4071 ): Collection.Indexed<Z>;
4072 zipWith<U, V, Z>(
4073 zipper: (value: T, otherValue: U, thirdValue: V) => Z,
4074 otherCollection: Collection<unknown, U>,
4075 thirdCollection: Collection<unknown, V>
4076 ): Collection.Indexed<Z>;
4077 zipWith<Z>(
4078 zipper: (...values: Array<unknown>) => Z,
4079 ...collections: Array<Collection<unknown, unknown>>
4080 ): Collection.Indexed<Z>;
4081
4082 // Search for value
4083
4084 /**
4085 * Returns the first index at which a given value can be found in the
4086 * Collection, or -1 if it is not present.
4087 */
4088 indexOf(searchValue: T): number;
4089
4090 /**
4091 * Returns the last index at which a given value can be found in the
4092 * Collection, or -1 if it is not present.
4093 */
4094 lastIndexOf(searchValue: T): number;
4095
4096 /**
4097 * Returns the first index in the Collection where a value satisfies the
4098 * provided predicate function. Otherwise -1 is returned.
4099 */
4100 findIndex(
4101 predicate: (value: T, index: number, iter: this) => boolean,
4102 context?: unknown
4103 ): number;
4104
4105 /**
4106 * Returns the last index in the Collection where a value satisfies the
4107 * provided predicate function. Otherwise -1 is returned.
4108 */
4109 findLastIndex(
4110 predicate: (value: T, index: number, iter: this) => boolean,
4111 context?: unknown
4112 ): number;
4113
4114 // Sequence algorithms
4115
4116 /**
4117 * Returns a new Collection with other collections concatenated to this one.
4118 */
4119 concat<C>(
4120 ...valuesOrCollections: Array<Iterable<C> | C>
4121 ): Collection.Indexed<T | C>;
4122
4123 /**
4124 * Returns a new Collection.Indexed with values passed through a
4125 * `mapper` function.
4126 *
4127 * ```js
4128 * const { Collection } = require('immutable')
4129 * Collection.Indexed([1,2]).map(x => 10 * x)
4130 * // Seq [ 1, 2 ]
4131 * ```
4132 *
4133 * Note: `map()` always returns a new instance, even if it produced the
4134 * same value at every step.
4135 */
4136 map<M>(
4137 mapper: (value: T, key: number, iter: this) => M,
4138 context?: unknown
4139 ): Collection.Indexed<M>;
4140
4141 /**
4142 * Flat-maps the Collection, returning a Collection of the same type.
4143 *
4144 * Similar to `collection.map(...).flatten(true)`.
4145 */
4146 flatMap<M>(
4147 mapper: (value: T, key: number, iter: this) => Iterable<M>,
4148 context?: unknown
4149 ): Collection.Indexed<M>;
4150
4151 /**
4152 * Returns a new Collection with only the values for which the `predicate`
4153 * function returns true.
4154 *
4155 * Note: `filter()` always returns a new instance, even if it results in
4156 * not filtering out any values.
4157 */
4158 filter<F extends T>(
4159 predicate: (value: T, index: number, iter: this) => value is F,
4160 context?: unknown
4161 ): Collection.Indexed<F>;
4162 filter(
4163 predicate: (value: T, index: number, iter: this) => unknown,
4164 context?: unknown
4165 ): this;
4166
4167 /**
4168 * Returns a new indexed Collection with the values for which the
4169 * `predicate` function returns false and another for which is returns
4170 * true.
4171 */
4172 partition<F extends T, C>(
4173 predicate: (this: C, value: T, index: number, iter: this) => value is F,
4174 context?: C
4175 ): [Collection.Indexed<T>, Collection.Indexed<F>];
4176 partition<C>(
4177 predicate: (this: C, value: T, index: number, iter: this) => unknown,
4178 context?: C
4179 ): [this, this];
4180
4181 [Symbol.iterator](): IterableIterator<T>;
4182 }
4183
4184 /**
4185 * Set Collections only represent values. They have no associated keys or
4186 * indices. Duplicate values are possible in the lazy `Seq.Set`s, however
4187 * the concrete `Set` Collection does not allow duplicate values.
4188 *
4189 * Collection methods on Collection.Set such as `map` and `forEach` will provide
4190 * the value as both the first and second arguments to the provided function.
4191 *
4192 * ```js
4193 * const { Collection } = require('immutable')
4194 * const seq = Collection.Set([ 'A', 'B', 'C' ])
4195 * // Seq { "A", "B", "C" }
4196 * seq.forEach((v, k) =>
4197 * assert.equal(v, k)
4198 * )
4199 * ```
4200 */
4201 namespace Set {}
4202
4203 /**
4204 * Similar to `Collection()`, but always returns a Collection.Set.
4205 *
4206 * Note: `Collection.Set` is a factory function and not a class, and does
4207 * not use the `new` keyword during construction.
4208 */
4209 function Set<T>(collection?: Iterable<T> | ArrayLike<T>): Collection.Set<T>;
4210
4211 interface Set<T> extends Collection<T, T> {
4212 /**
4213 * Deeply converts this Set collection to equivalent native JavaScript Array.
4214 */
4215 toJS(): Array<DeepCopy<T>>;
4216
4217 /**
4218 * Shallowly converts this Set collection to equivalent native JavaScript Array.
4219 */
4220 toJSON(): Array<T>;
4221
4222 /**
4223 * Shallowly converts this collection to an Array.
4224 */
4225 toArray(): Array<T>;
4226
4227 /**
4228 * Returns Seq.Set.
4229 * @override
4230 */
4231 toSeq(): Seq.Set<T>;
4232
4233 // Sequence algorithms
4234
4235 /**
4236 * Returns a new Collection with other collections concatenated to this one.
4237 */
4238 concat<U>(...collections: Array<Iterable<U>>): Collection.Set<T | U>;
4239
4240 /**
4241 * Returns a new Collection.Set with values passed through a
4242 * `mapper` function.
4243 *
4244 * ```
4245 * Collection.Set([ 1, 2 ]).map(x => 10 * x)
4246 * // Seq { 1, 2 }
4247 * ```
4248 *
4249 * Note: `map()` always returns a new instance, even if it produced the
4250 * same value at every step.
4251 */
4252 map<M>(
4253 mapper: (value: T, key: T, iter: this) => M,
4254 context?: unknown
4255 ): Collection.Set<M>;
4256
4257 /**
4258 * Flat-maps the Collection, returning a Collection of the same type.
4259 *
4260 * Similar to `collection.map(...).flatten(true)`.
4261 */
4262 flatMap<M>(
4263 mapper: (value: T, key: T, iter: this) => Iterable<M>,
4264 context?: unknown
4265 ): Collection.Set<M>;
4266
4267 /**
4268 * Returns a new Collection with only the values for which the `predicate`
4269 * function returns true.
4270 *
4271 * Note: `filter()` always returns a new instance, even if it results in
4272 * not filtering out any values.
4273 */
4274 filter<F extends T>(
4275 predicate: (value: T, key: T, iter: this) => value is F,
4276 context?: unknown
4277 ): Collection.Set<F>;
4278 filter(
4279 predicate: (value: T, key: T, iter: this) => unknown,
4280 context?: unknown
4281 ): this;
4282
4283 /**
4284 * Returns a new set Collection with the values for which the
4285 * `predicate` function returns false and another for which is returns
4286 * true.
4287 */
4288 partition<F extends T, C>(
4289 predicate: (this: C, value: T, key: T, iter: this) => value is F,
4290 context?: C
4291 ): [Collection.Set<T>, Collection.Set<F>];
4292 partition<C>(
4293 predicate: (this: C, value: T, key: T, iter: this) => unknown,
4294 context?: C
4295 ): [this, this];
4296
4297 [Symbol.iterator](): IterableIterator<T>;
4298 }
4299 }
4300
4301 /**
4302 * Creates a Collection.
4303 *
4304 * The type of Collection created is based on the input.
4305 *
4306 * * If an `Collection`, that same `Collection`.
4307 * * If an Array-like, an `Collection.Indexed`.
4308 * * If an Object with an Iterator defined, an `Collection.Indexed`.
4309 * * If an Object, an `Collection.Keyed`.
4310 *
4311 * This methods forces the conversion of Objects and Strings to Collections.
4312 * If you want to ensure that a Collection of one item is returned, use
4313 * `Seq.of`.
4314 *
4315 * Note: An Iterator itself will be treated as an object, becoming a `Seq.Keyed`,
4316 * which is usually not what you want. You should turn your Iterator Object into
4317 * an iterable object by defining a Symbol.iterator (or @@iterator) method which
4318 * returns `this`.
4319 *
4320 * Note: `Collection` is a conversion function and not a class, and does not
4321 * use the `new` keyword during construction.
4322 */
4323 function Collection<I extends Collection<unknown, unknown>>(collection: I): I;
4324 function Collection<T>(
4325 collection: Iterable<T> | ArrayLike<T>
4326 ): Collection.Indexed<T>;
4327 function Collection<V>(obj: {
4328 [key: string]: V;
4329 }): Collection.Keyed<string, V>;
4330 function Collection<K = unknown, V = unknown>(): Collection<K, V>;
4331
4332 interface Collection<K, V> extends ValueObject {
4333 // Value equality
4334
4335 /**
4336 * True if this and the other Collection have value equality, as defined
4337 * by `Immutable.is()`.
4338 *
4339 * Note: This is equivalent to `Immutable.is(this, other)`, but provided to
4340 * allow for chained expressions.
4341 */
4342 equals(other: unknown): boolean;
4343
4344 /**
4345 * Computes and returns the hashed identity for this Collection.
4346 *
4347 * The `hashCode` of a Collection is used to determine potential equality,
4348 * and is used when adding this to a `Set` or as a key in a `Map`, enabling
4349 * lookup via a different instance.
4350 *
4351 * <!-- runkit:activate
4352 * { "preamble": "const { Set, List } = require('immutable')" }
4353 * -->
4354 * ```js
4355 * const a = List([ 1, 2, 3 ]);
4356 * const b = List([ 1, 2, 3 ]);
4357 * assert.notStrictEqual(a, b); // different instances
4358 * const set = Set([ a ]);
4359 * assert.equal(set.has(b), true);
4360 * ```
4361 *
4362 * If two values have the same `hashCode`, they are [not guaranteed
4363 * to be equal][Hash Collision]. If two values have different `hashCode`s,
4364 * they must not be equal.
4365 *
4366 * [Hash Collision]: https://en.wikipedia.org/wiki/Collision_(computer_science)
4367 */
4368 hashCode(): number;
4369
4370 // Reading values
4371
4372 /**
4373 * Returns the value associated with the provided key, or notSetValue if
4374 * the Collection does not contain this key.
4375 *
4376 * Note: it is possible a key may be associated with an `undefined` value,
4377 * so if `notSetValue` is not provided and this method returns `undefined`,
4378 * that does not guarantee the key was not found.
4379 */
4380 get<NSV>(key: K, notSetValue: NSV): V | NSV;
4381 get(key: K): V | undefined;
4382
4383 /**
4384 * True if a key exists within this `Collection`, using `Immutable.is`
4385 * to determine equality
4386 */
4387 has(key: K): boolean;
4388
4389 /**
4390 * True if a value exists within this `Collection`, using `Immutable.is`
4391 * to determine equality
4392 * @alias contains
4393 */
4394 includes(value: V): boolean;
4395 contains(value: V): boolean;
4396
4397 /**
4398 * In case the `Collection` is not empty returns the first element of the
4399 * `Collection`.
4400 * In case the `Collection` is empty returns the optional default
4401 * value if provided, if no default value is provided returns undefined.
4402 */
4403 first<NSV>(notSetValue: NSV): V | NSV;
4404 first(): V | undefined;
4405
4406 /**
4407 * In case the `Collection` is not empty returns the last element of the
4408 * `Collection`.
4409 * In case the `Collection` is empty returns the optional default
4410 * value if provided, if no default value is provided returns undefined.
4411 */
4412 last<NSV>(notSetValue: NSV): V | NSV;
4413 last(): V | undefined;
4414
4415 // Reading deep values
4416
4417 /**
4418 * Returns the value found by following a path of keys or indices through
4419 * nested Collections.
4420 *
4421 * <!-- runkit:activate -->
4422 * ```js
4423 * const { Map, List } = require('immutable')
4424 * const deepData = Map({ x: List([ Map({ y: 123 }) ]) });
4425 * deepData.getIn(['x', 0, 'y']) // 123
4426 * ```
4427 *
4428 * Plain JavaScript Object or Arrays may be nested within an Immutable.js
4429 * Collection, and getIn() can access those values as well:
4430 *
4431 * <!-- runkit:activate -->
4432 * ```js
4433 * const { Map, List } = require('immutable')
4434 * const deepData = Map({ x: [ { y: 123 } ] });
4435 * deepData.getIn(['x', 0, 'y']) // 123
4436 * ```
4437 */
4438 getIn(searchKeyPath: Iterable<unknown>, notSetValue?: unknown): unknown;
4439
4440 /**
4441 * True if the result of following a path of keys or indices through nested
4442 * Collections results in a set value.
4443 */
4444 hasIn(searchKeyPath: Iterable<unknown>): boolean;
4445
4446 // Persistent changes
4447
4448 /**
4449 * This can be very useful as a way to "chain" a normal function into a
4450 * sequence of methods. RxJS calls this "let" and lodash calls it "thru".
4451 *
4452 * For example, to sum a Seq after mapping and filtering:
4453 *
4454 * <!-- runkit:activate -->
4455 * ```js
4456 * const { Seq } = require('immutable')
4457 *
4458 * function sum(collection) {
4459 * return collection.reduce((sum, x) => sum + x, 0)
4460 * }
4461 *
4462 * Seq([ 1, 2, 3 ])
4463 * .map(x => x + 1)
4464 * .filter(x => x % 2 === 0)
4465 * .update(sum)
4466 * // 6
4467 * ```
4468 */
4469 update<R>(updater: (value: this) => R): R;
4470
4471 // Conversion to JavaScript types
4472
4473 /**
4474 * Deeply converts this Collection to equivalent native JavaScript Array or Object.
4475 *
4476 * `Collection.Indexed`, and `Collection.Set` become `Array`, while
4477 * `Collection.Keyed` become `Object`, converting keys to Strings.
4478 */
4479 toJS():
4480 | Array<DeepCopy<V>>
4481 | { [key in string | number | symbol]: DeepCopy<V> };
4482
4483 /**
4484 * Shallowly converts this Collection to equivalent native JavaScript Array or Object.
4485 *
4486 * `Collection.Indexed`, and `Collection.Set` become `Array`, while
4487 * `Collection.Keyed` become `Object`, converting keys to Strings.
4488 */
4489 toJSON(): Array<V> | { [key in string | number | symbol]: V };
4490
4491 /**
4492 * Shallowly converts this collection to an Array.
4493 *
4494 * `Collection.Indexed`, and `Collection.Set` produce an Array of values.
4495 * `Collection.Keyed` produce an Array of [key, value] tuples.
4496 */
4497 toArray(): Array<V> | Array<[K, V]>;
4498
4499 /**
4500 * Shallowly converts this Collection to an Object.
4501 *
4502 * Converts keys to Strings.
4503 */
4504 toObject(): { [key: string]: V };
4505
4506 // Conversion to Collections
4507
4508 /**
4509 * Converts this Collection to a Map, Throws if keys are not hashable.
4510 *
4511 * Note: This is equivalent to `Map(this.toKeyedSeq())`, but provided
4512 * for convenience and to allow for chained expressions.
4513 */
4514 toMap(): Map<K, V>;
4515
4516 /**
4517 * Converts this Collection to a Map, maintaining the order of iteration.
4518 *
4519 * Note: This is equivalent to `OrderedMap(this.toKeyedSeq())`, but
4520 * provided for convenience and to allow for chained expressions.
4521 */
4522 toOrderedMap(): OrderedMap<K, V>;
4523
4524 /**
4525 * Converts this Collection to a Set, discarding keys. Throws if values
4526 * are not hashable.
4527 *
4528 * Note: This is equivalent to `Set(this)`, but provided to allow for
4529 * chained expressions.
4530 */
4531 toSet(): Set<V>;
4532
4533 /**
4534 * Converts this Collection to a Set, maintaining the order of iteration and
4535 * discarding keys.
4536 *
4537 * Note: This is equivalent to `OrderedSet(this.valueSeq())`, but provided
4538 * for convenience and to allow for chained expressions.
4539 */
4540 toOrderedSet(): OrderedSet<V>;
4541
4542 /**
4543 * Converts this Collection to a List, discarding keys.
4544 *
4545 * This is similar to `List(collection)`, but provided to allow for chained
4546 * expressions. However, when called on `Map` or other keyed collections,
4547 * `collection.toList()` discards the keys and creates a list of only the
4548 * values, whereas `List(collection)` creates a list of entry tuples.
4549 *
4550 * <!-- runkit:activate -->
4551 * ```js
4552 * const { Map, List } = require('immutable')
4553 * var myMap = Map({ a: 'Apple', b: 'Banana' })
4554 * List(myMap) // List [ [ "a", "Apple" ], [ "b", "Banana" ] ]
4555 * myMap.toList() // List [ "Apple", "Banana" ]
4556 * ```
4557 */
4558 toList(): List<V>;
4559
4560 /**
4561 * Converts this Collection to a Stack, discarding keys. Throws if values
4562 * are not hashable.
4563 *
4564 * Note: This is equivalent to `Stack(this)`, but provided to allow for
4565 * chained expressions.
4566 */
4567 toStack(): Stack<V>;
4568
4569 // Conversion to Seq
4570
4571 /**
4572 * Converts this Collection to a Seq of the same kind (indexed,
4573 * keyed, or set).
4574 */
4575 toSeq(): Seq<K, V>;
4576
4577 /**
4578 * Returns a Seq.Keyed from this Collection where indices are treated as keys.
4579 *
4580 * This is useful if you want to operate on an
4581 * Collection.Indexed and preserve the [index, value] pairs.
4582 *
4583 * The returned Seq will have identical iteration order as
4584 * this Collection.
4585 *
4586 * <!-- runkit:activate -->
4587 * ```js
4588 * const { Seq } = require('immutable')
4589 * const indexedSeq = Seq([ 'A', 'B', 'C' ])
4590 * // Seq [ "A", "B", "C" ]
4591 * indexedSeq.filter(v => v === 'B')
4592 * // Seq [ "B" ]
4593 * const keyedSeq = indexedSeq.toKeyedSeq()
4594 * // Seq { 0: "A", 1: "B", 2: "C" }
4595 * keyedSeq.filter(v => v === 'B')
4596 * // Seq { 1: "B" }
4597 * ```
4598 */
4599 toKeyedSeq(): Seq.Keyed<K, V>;
4600
4601 /**
4602 * Returns an Seq.Indexed of the values of this Collection, discarding keys.
4603 */
4604 toIndexedSeq(): Seq.Indexed<V>;
4605
4606 /**
4607 * Returns a Seq.Set of the values of this Collection, discarding keys.
4608 */
4609 toSetSeq(): Seq.Set<V>;
4610
4611 // Iterators
4612
4613 /**
4614 * An iterator of this `Collection`'s keys.
4615 *
4616 * Note: this will return an ES6 iterator which does not support
4617 * Immutable.js sequence algorithms. Use `keySeq` instead, if this is
4618 * what you want.
4619 */
4620 keys(): IterableIterator<K>;
4621
4622 /**
4623 * An iterator of this `Collection`'s values.
4624 *
4625 * Note: this will return an ES6 iterator which does not support
4626 * Immutable.js sequence algorithms. Use `valueSeq` instead, if this is
4627 * what you want.
4628 */
4629 values(): IterableIterator<V>;
4630
4631 /**
4632 * An iterator of this `Collection`'s entries as `[ key, value ]` tuples.
4633 *
4634 * Note: this will return an ES6 iterator which does not support
4635 * Immutable.js sequence algorithms. Use `entrySeq` instead, if this is
4636 * what you want.
4637 */
4638 entries(): IterableIterator<[K, V]>;
4639
4640 [Symbol.iterator](): IterableIterator<unknown>;
4641
4642 // Collections (Seq)
4643
4644 /**
4645 * Returns a new Seq.Indexed of the keys of this Collection,
4646 * discarding values.
4647 */
4648 keySeq(): Seq.Indexed<K>;
4649
4650 /**
4651 * Returns an Seq.Indexed of the values of this Collection, discarding keys.
4652 */
4653 valueSeq(): Seq.Indexed<V>;
4654
4655 /**
4656 * Returns a new Seq.Indexed of [key, value] tuples.
4657 */
4658 entrySeq(): Seq.Indexed<[K, V]>;
4659
4660 // Sequence algorithms
4661
4662 /**
4663 * Returns a new Collection of the same type with values passed through a
4664 * `mapper` function.
4665 *
4666 * <!-- runkit:activate -->
4667 * ```js
4668 * const { Collection } = require('immutable')
4669 * Collection({ a: 1, b: 2 }).map(x => 10 * x)
4670 * // Seq { "a": 10, "b": 20 }
4671 * ```
4672 *
4673 * Note: `map()` always returns a new instance, even if it produced the same
4674 * value at every step.
4675 */
4676 map<M>(
4677 mapper: (value: V, key: K, iter: this) => M,
4678 context?: unknown
4679 ): Collection<K, M>;
4680
4681 /**
4682 * Note: used only for sets, which return Collection<M, M> but are otherwise
4683 * identical to normal `map()`.
4684 *
4685 * @ignore
4686 */
4687 map(...args: Array<never>): unknown;
4688
4689 /**
4690 * Returns a new Collection of the same type with only the entries for which
4691 * the `predicate` function returns true.
4692 *
4693 * <!-- runkit:activate -->
4694 * ```js
4695 * const { Map } = require('immutable')
4696 * Map({ a: 1, b: 2, c: 3, d: 4}).filter(x => x % 2 === 0)
4697 * // Map { "b": 2, "d": 4 }
4698 * ```
4699 *
4700 * Note: `filter()` always returns a new instance, even if it results in
4701 * not filtering out any values.
4702 */
4703 filter<F extends V>(
4704 predicate: (value: V, key: K, iter: this) => value is F,
4705 context?: unknown
4706 ): Collection<K, F>;
4707 filter(
4708 predicate: (value: V, key: K, iter: this) => unknown,
4709 context?: unknown
4710 ): this;
4711
4712 /**
4713 * Returns a new Collection of the same type with only the entries for which
4714 * the `predicate` function returns false.
4715 *
4716 * <!-- runkit:activate -->
4717 * ```js
4718 * const { Map } = require('immutable')
4719 * Map({ a: 1, b: 2, c: 3, d: 4}).filterNot(x => x % 2 === 0)
4720 * // Map { "a": 1, "c": 3 }
4721 * ```
4722 *
4723 * Note: `filterNot()` always returns a new instance, even if it results in
4724 * not filtering out any values.
4725 */
4726 filterNot(
4727 predicate: (value: V, key: K, iter: this) => boolean,
4728 context?: unknown
4729 ): this;
4730
4731 /**
4732 * Returns a new Collection with the values for which the `predicate`
4733 * function returns false and another for which is returns true.
4734 */
4735 partition<F extends V, C>(
4736 predicate: (this: C, value: V, key: K, iter: this) => value is F,
4737 context?: C
4738 ): [Collection<K, V>, Collection<K, F>];
4739 partition<C>(
4740 predicate: (this: C, value: V, key: K, iter: this) => unknown,
4741 context?: C
4742 ): [this, this];
4743
4744 /**
4745 * Returns a new Collection of the same type in reverse order.
4746 */
4747 reverse(): this;
4748
4749 /**
4750 * Returns a new Collection of the same type which includes the same entries,
4751 * stably sorted by using a `comparator`.
4752 *
4753 * If a `comparator` is not provided, a default comparator uses `<` and `>`.
4754 *
4755 * `comparator(valueA, valueB)`:
4756 *
4757 * * Returns `0` if the elements should not be swapped.
4758 * * Returns `-1` (or any negative number) if `valueA` comes before `valueB`
4759 * * Returns `1` (or any positive number) if `valueA` comes after `valueB`
4760 * * Alternatively, can return a value of the `PairSorting` enum type
4761 * * Is pure, i.e. it must always return the same value for the same pair
4762 * of values.
4763 *
4764 * When sorting collections which have no defined order, their ordered
4765 * equivalents will be returned. e.g. `map.sort()` returns OrderedMap.
4766 *
4767 * <!-- runkit:activate -->
4768 * ```js
4769 * const { Map } = require('immutable')
4770 * Map({ "c": 3, "a": 1, "b": 2 }).sort((a, b) => {
4771 * if (a < b) { return -1; }
4772 * if (a > b) { return 1; }
4773 * if (a === b) { return 0; }
4774 * });
4775 * // OrderedMap { "a": 1, "b": 2, "c": 3 }
4776 * ```
4777 *
4778 * Note: `sort()` Always returns a new instance, even if the original was
4779 * already sorted.
4780 *
4781 * Note: This is always an eager operation.
4782 */
4783 sort(comparator?: Comparator<V>): this;
4784
4785 /**
4786 * Like `sort`, but also accepts a `comparatorValueMapper` which allows for
4787 * sorting by more sophisticated means:
4788 *
4789 * <!-- runkit:activate -->
4790 * ```js
4791 * const { Map } = require('immutable')
4792 * const beattles = Map({
4793 * John: { name: "Lennon" },
4794 * Paul: { name: "McCartney" },
4795 * George: { name: "Harrison" },
4796 * Ringo: { name: "Starr" },
4797 * });
4798 * beattles.sortBy(member => member.name);
4799 * ```
4800 *
4801 * Note: `sortBy()` Always returns a new instance, even if the original was
4802 * already sorted.
4803 *
4804 * Note: This is always an eager operation.
4805 */
4806 sortBy<C>(
4807 comparatorValueMapper: (value: V, key: K, iter: this) => C,
4808 comparator?: Comparator<C>
4809 ): this;
4810
4811 /**
4812 * Returns a `Map` of `Collection`, grouped by the return
4813 * value of the `grouper` function.
4814 *
4815 * Note: This is always an eager operation.
4816 *
4817 * <!-- runkit:activate -->
4818 * ```js
4819 * const { List, Map } = require('immutable')
4820 * const listOfMaps = List([
4821 * Map({ v: 0 }),
4822 * Map({ v: 1 }),
4823 * Map({ v: 1 }),
4824 * Map({ v: 0 }),
4825 * Map({ v: 2 })
4826 * ])
4827 * const groupsOfMaps = listOfMaps.groupBy(x => x.get('v'))
4828 * // Map {
4829 * // 0: List [ Map{ "v": 0 }, Map { "v": 0 } ],
4830 * // 1: List [ Map{ "v": 1 }, Map { "v": 1 } ],
4831 * // 2: List [ Map{ "v": 2 } ],
4832 * // }
4833 * ```
4834 */
4835 groupBy<G>(
4836 grouper: (value: V, key: K, iter: this) => G,
4837 context?: unknown
4838 ): Map<G, this>;
4839
4840 // Side effects
4841
4842 /**
4843 * The `sideEffect` is executed for every entry in the Collection.
4844 *
4845 * Unlike `Array#forEach`, if any call of `sideEffect` returns
4846 * `false`, the iteration will stop. Returns the number of entries iterated
4847 * (including the last iteration which returned false).
4848 */
4849 forEach(
4850 sideEffect: (value: V, key: K, iter: this) => unknown,
4851 context?: unknown
4852 ): number;
4853
4854 // Creating subsets
4855
4856 /**
4857 * Returns a new Collection of the same type representing a portion of this
4858 * Collection from start up to but not including end.
4859 *
4860 * If begin is negative, it is offset from the end of the Collection. e.g.
4861 * `slice(-2)` returns a Collection of the last two entries. If it is not
4862 * provided the new Collection will begin at the beginning of this Collection.
4863 *
4864 * If end is negative, it is offset from the end of the Collection. e.g.
4865 * `slice(0, -1)` returns a Collection of everything but the last entry. If
4866 * it is not provided, the new Collection will continue through the end of
4867 * this Collection.
4868 *
4869 * If the requested slice is equivalent to the current Collection, then it
4870 * will return itself.
4871 */
4872 slice(begin?: number, end?: number): this;
4873
4874 /**
4875 * Returns a new Collection of the same type containing all entries except
4876 * the first.
4877 */
4878 rest(): this;
4879
4880 /**
4881 * Returns a new Collection of the same type containing all entries except
4882 * the last.
4883 */
4884 butLast(): this;
4885
4886 /**
4887 * Returns a new Collection of the same type which excludes the first `amount`
4888 * entries from this Collection.
4889 */
4890 skip(amount: number): this;
4891
4892 /**
4893 * Returns a new Collection of the same type which excludes the last `amount`
4894 * entries from this Collection.
4895 */
4896 skipLast(amount: number): this;
4897
4898 /**
4899 * Returns a new Collection of the same type which includes entries starting
4900 * from when `predicate` first returns false.
4901 *
4902 * <!-- runkit:activate -->
4903 * ```js
4904 * const { List } = require('immutable')
4905 * List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
4906 * .skipWhile(x => x.match(/g/))
4907 * // List [ "cat", "hat", "god" ]
4908 * ```
4909 */
4910 skipWhile(
4911 predicate: (value: V, key: K, iter: this) => boolean,
4912 context?: unknown
4913 ): this;
4914
4915 /**
4916 * Returns a new Collection of the same type which includes entries starting
4917 * from when `predicate` first returns true.
4918 *
4919 * <!-- runkit:activate -->
4920 * ```js
4921 * const { List } = require('immutable')
4922 * List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
4923 * .skipUntil(x => x.match(/hat/))
4924 * // List [ "hat", "god" ]
4925 * ```
4926 */
4927 skipUntil(
4928 predicate: (value: V, key: K, iter: this) => boolean,
4929 context?: unknown
4930 ): this;
4931
4932 /**
4933 * Returns a new Collection of the same type which includes the first `amount`
4934 * entries from this Collection.
4935 */
4936 take(amount: number): this;
4937
4938 /**
4939 * Returns a new Collection of the same type which includes the last `amount`
4940 * entries from this Collection.
4941 */
4942 takeLast(amount: number): this;
4943
4944 /**
4945 * Returns a new Collection of the same type which includes entries from this
4946 * Collection as long as the `predicate` returns true.
4947 *
4948 * <!-- runkit:activate -->
4949 * ```js
4950 * const { List } = require('immutable')
4951 * List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
4952 * .takeWhile(x => x.match(/o/))
4953 * // List [ "dog", "frog" ]
4954 * ```
4955 */
4956 takeWhile(
4957 predicate: (value: V, key: K, iter: this) => boolean,
4958 context?: unknown
4959 ): this;
4960
4961 /**
4962 * Returns a new Collection of the same type which includes entries from this
4963 * Collection as long as the `predicate` returns false.
4964 *
4965 * <!-- runkit:activate -->
4966 * ```js
4967 * const { List } = require('immutable')
4968 * List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
4969 * .takeUntil(x => x.match(/at/))
4970 * // List [ "dog", "frog" ]
4971 * ```
4972 */
4973 takeUntil(
4974 predicate: (value: V, key: K, iter: this) => boolean,
4975 context?: unknown
4976 ): this;
4977
4978 // Combination
4979
4980 /**
4981 * Returns a new Collection of the same type with other values and
4982 * collection-like concatenated to this one.
4983 *
4984 * For Seqs, all entries will be present in the resulting Seq, even if they
4985 * have the same key.
4986 */
4987 concat(
4988 ...valuesOrCollections: Array<unknown>
4989 ): Collection<unknown, unknown>;
4990
4991 /**
4992 * Flattens nested Collections.
4993 *
4994 * Will deeply flatten the Collection by default, returning a Collection of the
4995 * same type, but a `depth` can be provided in the form of a number or
4996 * boolean (where true means to shallowly flatten one level). A depth of 0
4997 * (or shallow: false) will deeply flatten.
4998 *
4999 * Flattens only others Collection, not Arrays or Objects.
5000 *
5001 * Note: `flatten(true)` operates on Collection<unknown, Collection<K, V>> and
5002 * returns Collection<K, V>
5003 */
5004 flatten(depth?: number): Collection<unknown, unknown>;
5005 flatten(shallow?: boolean): Collection<unknown, unknown>;
5006
5007 /**
5008 * Flat-maps the Collection, returning a Collection of the same type.
5009 *
5010 * Similar to `collection.map(...).flatten(true)`.
5011 */
5012 flatMap<M>(
5013 mapper: (value: V, key: K, iter: this) => Iterable<M>,
5014 context?: unknown
5015 ): Collection<K, M>;
5016
5017 /**
5018 * Flat-maps the Collection, returning a Collection of the same type.
5019 *
5020 * Similar to `collection.map(...).flatten(true)`.
5021 * Used for Dictionaries only.
5022 */
5023 flatMap<KM, VM>(
5024 mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,
5025 context?: unknown
5026 ): Collection<KM, VM>;
5027
5028 // Reducing a value
5029
5030 /**
5031 * Reduces the Collection to a value by calling the `reducer` for every entry
5032 * in the Collection and passing along the reduced value.
5033 *
5034 * If `initialReduction` is not provided, the first item in the
5035 * Collection will be used.
5036 *
5037 * @see `Array#reduce`.
5038 */
5039 reduce<R>(
5040 reducer: (reduction: R, value: V, key: K, iter: this) => R,
5041 initialReduction: R,
5042 context?: unknown
5043 ): R;
5044 reduce<R>(
5045 reducer: (reduction: V | R, value: V, key: K, iter: this) => R
5046 ): R;
5047
5048 /**
5049 * Reduces the Collection in reverse (from the right side).
5050 *
5051 * Note: Similar to this.reverse().reduce(), and provided for parity
5052 * with `Array#reduceRight`.
5053 */
5054 reduceRight<R>(
5055 reducer: (reduction: R, value: V, key: K, iter: this) => R,
5056 initialReduction: R,
5057 context?: unknown
5058 ): R;
5059 reduceRight<R>(
5060 reducer: (reduction: V | R, value: V, key: K, iter: this) => R
5061 ): R;
5062
5063 /**
5064 * True if `predicate` returns true for all entries in the Collection.
5065 */
5066 every(
5067 predicate: (value: V, key: K, iter: this) => boolean,
5068 context?: unknown
5069 ): boolean;
5070
5071 /**
5072 * True if `predicate` returns true for any entry in the Collection.
5073 */
5074 some(
5075 predicate: (value: V, key: K, iter: this) => boolean,
5076 context?: unknown
5077 ): boolean;
5078
5079 /**
5080 * Joins values together as a string, inserting a separator between each.
5081 * The default separator is `","`.
5082 */
5083 join(separator?: string): string;
5084
5085 /**
5086 * Returns true if this Collection includes no values.
5087 *
5088 * For some lazy `Seq`, `isEmpty` might need to iterate to determine
5089 * emptiness. At most one iteration will occur.
5090 */
5091 isEmpty(): boolean;
5092
5093 /**
5094 * Returns the size of this Collection.
5095 *
5096 * Regardless of if this Collection can describe its size lazily (some Seqs
5097 * cannot), this method will always return the correct size. E.g. it
5098 * evaluates a lazy `Seq` if necessary.
5099 *
5100 * If `predicate` is provided, then this returns the count of entries in the
5101 * Collection for which the `predicate` returns true.
5102 */
5103 count(): number;
5104 count(
5105 predicate: (value: V, key: K, iter: this) => boolean,
5106 context?: unknown
5107 ): number;
5108
5109 /**
5110 * Returns a `Seq.Keyed` of counts, grouped by the return value of
5111 * the `grouper` function.
5112 *
5113 * Note: This is not a lazy operation.
5114 */
5115 countBy<G>(
5116 grouper: (value: V, key: K, iter: this) => G,
5117 context?: unknown
5118 ): Map<G, number>;
5119
5120 // Search for value
5121
5122 /**
5123 * Returns the first value for which the `predicate` returns true.
5124 */
5125 find(
5126 predicate: (value: V, key: K, iter: this) => boolean,
5127 context?: unknown,
5128 notSetValue?: V
5129 ): V | undefined;
5130
5131 /**
5132 * Returns the last value for which the `predicate` returns true.
5133 *
5134 * Note: `predicate` will be called for each entry in reverse.
5135 */
5136 findLast(
5137 predicate: (value: V, key: K, iter: this) => boolean,
5138 context?: unknown,
5139 notSetValue?: V
5140 ): V | undefined;
5141
5142 /**
5143 * Returns the first [key, value] entry for which the `predicate` returns true.
5144 */
5145 findEntry(
5146 predicate: (value: V, key: K, iter: this) => boolean,
5147 context?: unknown,
5148 notSetValue?: V
5149 ): [K, V] | undefined;
5150
5151 /**
5152 * Returns the last [key, value] entry for which the `predicate`
5153 * returns true.
5154 *
5155 * Note: `predicate` will be called for each entry in reverse.
5156 */
5157 findLastEntry(
5158 predicate: (value: V, key: K, iter: this) => boolean,
5159 context?: unknown,
5160 notSetValue?: V
5161 ): [K, V] | undefined;
5162
5163 /**
5164 * Returns the key for which the `predicate` returns true.
5165 */
5166 findKey(
5167 predicate: (value: V, key: K, iter: this) => boolean,
5168 context?: unknown
5169 ): K | undefined;
5170
5171 /**
5172 * Returns the last key for which the `predicate` returns true.
5173 *
5174 * Note: `predicate` will be called for each entry in reverse.
5175 */
5176 findLastKey(
5177 predicate: (value: V, key: K, iter: this) => boolean,
5178 context?: unknown
5179 ): K | undefined;
5180
5181 /**
5182 * Returns the key associated with the search value, or undefined.
5183 */
5184 keyOf(searchValue: V): K | undefined;
5185
5186 /**
5187 * Returns the last key associated with the search value, or undefined.
5188 */
5189 lastKeyOf(searchValue: V): K | undefined;
5190
5191 /**
5192 * Returns the maximum value in this collection. If any values are
5193 * comparatively equivalent, the first one found will be returned.
5194 *
5195 * The `comparator` is used in the same way as `Collection#sort`. If it is not
5196 * provided, the default comparator is `>`.
5197 *
5198 * When two values are considered equivalent, the first encountered will be
5199 * returned. Otherwise, `max` will operate independent of the order of input
5200 * as long as the comparator is commutative. The default comparator `>` is
5201 * commutative *only* when types do not differ.
5202 *
5203 * If `comparator` returns 0 and either value is NaN, undefined, or null,
5204 * that value will be returned.
5205 */
5206 max(comparator?: Comparator<V>): V | undefined;
5207
5208 /**
5209 * Like `max`, but also accepts a `comparatorValueMapper` which allows for
5210 * comparing by more sophisticated means:
5211 *
5212 * <!-- runkit:activate -->
5213 * ```js
5214 * const { List, } = require('immutable');
5215 * const l = List([
5216 * { name: 'Bob', avgHit: 1 },
5217 * { name: 'Max', avgHit: 3 },
5218 * { name: 'Lili', avgHit: 2 } ,
5219 * ]);
5220 * l.maxBy(i => i.avgHit); // will output { name: 'Max', avgHit: 3 }
5221 * ```
5222 */
5223 maxBy<C>(
5224 comparatorValueMapper: (value: V, key: K, iter: this) => C,
5225 comparator?: Comparator<C>
5226 ): V | undefined;
5227
5228 /**
5229 * Returns the minimum value in this collection. If any values are
5230 * comparatively equivalent, the first one found will be returned.
5231 *
5232 * The `comparator` is used in the same way as `Collection#sort`. If it is not
5233 * provided, the default comparator is `<`.
5234 *
5235 * When two values are considered equivalent, the first encountered will be
5236 * returned. Otherwise, `min` will operate independent of the order of input
5237 * as long as the comparator is commutative. The default comparator `<` is
5238 * commutative *only* when types do not differ.
5239 *
5240 * If `comparator` returns 0 and either value is NaN, undefined, or null,
5241 * that value will be returned.
5242 */
5243 min(comparator?: Comparator<V>): V | undefined;
5244
5245 /**
5246 * Like `min`, but also accepts a `comparatorValueMapper` which allows for
5247 * comparing by more sophisticated means:
5248 *
5249 * <!-- runkit:activate -->
5250 * ```js
5251 * const { List, } = require('immutable');
5252 * const l = List([
5253 * { name: 'Bob', avgHit: 1 },
5254 * { name: 'Max', avgHit: 3 },
5255 * { name: 'Lili', avgHit: 2 } ,
5256 * ]);
5257 * l.minBy(i => i.avgHit); // will output { name: 'Bob', avgHit: 1 }
5258 * ```
5259 */
5260 minBy<C>(
5261 comparatorValueMapper: (value: V, key: K, iter: this) => C,
5262 comparator?: Comparator<C>
5263 ): V | undefined;
5264
5265 // Comparison
5266
5267 /**
5268 * True if `iter` includes every value in this Collection.
5269 */
5270 isSubset(iter: Iterable<V>): boolean;
5271
5272 /**
5273 * True if this Collection includes every value in `iter`.
5274 */
5275 isSuperset(iter: Iterable<V>): boolean;
5276 }
5277
5278 /**
5279 * The interface to fulfill to qualify as a Value Object.
5280 */
5281 interface ValueObject {
5282 /**
5283 * True if this and the other Collection have value equality, as defined
5284 * by `Immutable.is()`.
5285 *
5286 * Note: This is equivalent to `Immutable.is(this, other)`, but provided to
5287 * allow for chained expressions.
5288 */
5289 equals(other: unknown): boolean;
5290
5291 /**
5292 * Computes and returns the hashed identity for this Collection.
5293 *
5294 * The `hashCode` of a Collection is used to determine potential equality,
5295 * and is used when adding this to a `Set` or as a key in a `Map`, enabling
5296 * lookup via a different instance.
5297 *
5298 * <!-- runkit:activate -->
5299 * ```js
5300 * const { List, Set } = require('immutable');
5301 * const a = List([ 1, 2, 3 ]);
5302 * const b = List([ 1, 2, 3 ]);
5303 * assert.notStrictEqual(a, b); // different instances
5304 * const set = Set([ a ]);
5305 * assert.equal(set.has(b), true);
5306 * ```
5307 *
5308 * Note: hashCode() MUST return a Uint32 number. The easiest way to
5309 * guarantee this is to return `myHash | 0` from a custom implementation.
5310 *
5311 * If two values have the same `hashCode`, they are [not guaranteed
5312 * to be equal][Hash Collision]. If two values have different `hashCode`s,
5313 * they must not be equal.
5314 *
5315 * Note: `hashCode()` is not guaranteed to always be called before
5316 * `equals()`. Most but not all Immutable.js collections use hash codes to
5317 * organize their internal data structures, while all Immutable.js
5318 * collections use equality during lookups.
5319 *
5320 * [Hash Collision]: https://en.wikipedia.org/wiki/Collision_(computer_science)
5321 */
5322 hashCode(): number;
5323 }
5324
5325 /**
5326 * Deeply converts plain JS objects and arrays to Immutable Maps and Lists.
5327 *
5328 * `fromJS` will convert Arrays and [array-like objects][2] to a List, and
5329 * plain objects (without a custom prototype) to a Map. [Iterable objects][3]
5330 * may be converted to List, Map, or Set.
5331 *
5332 * If a `reviver` is optionally provided, it will be called with every
5333 * collection as a Seq (beginning with the most nested collections
5334 * and proceeding to the top-level collection itself), along with the key
5335 * referring to each collection and the parent JS object provided as `this`.
5336 * For the top level, object, the key will be `""`. This `reviver` is expected
5337 * to return a new Immutable Collection, allowing for custom conversions from
5338 * deep JS objects. Finally, a `path` is provided which is the sequence of
5339 * keys to this value from the starting value.
5340 *
5341 * `reviver` acts similarly to the [same parameter in `JSON.parse`][1].
5342 *
5343 * If `reviver` is not provided, the default behavior will convert Objects
5344 * into Maps and Arrays into Lists like so:
5345 *
5346 * <!-- runkit:activate -->
5347 * ```js
5348 * const { fromJS, isKeyed } = require('immutable')
5349 * function (key, value) {
5350 * return isKeyed(value) ? value.toMap() : value.toList()
5351 * }
5352 * ```
5353 *
5354 * Accordingly, this example converts native JS data to OrderedMap and List:
5355 *
5356 * <!-- runkit:activate -->
5357 * ```js
5358 * const { fromJS, isKeyed } = require('immutable')
5359 * fromJS({ a: {b: [10, 20, 30]}, c: 40}, function (key, value, path) {
5360 * console.log(key, value, path)
5361 * return isKeyed(value) ? value.toOrderedMap() : value.toList()
5362 * })
5363 *
5364 * > "b", [ 10, 20, 30 ], [ "a", "b" ]
5365 * > "a", {b: [10, 20, 30]}, [ "a" ]
5366 * > "", {a: {b: [10, 20, 30]}, c: 40}, []
5367 * ```
5368 *
5369 * Keep in mind, when using JS objects to construct Immutable Maps, that
5370 * JavaScript Object properties are always strings, even if written in a
5371 * quote-less shorthand, while Immutable Maps accept keys of any type.
5372 *
5373 * <!-- runkit:activate -->
5374 * ```js
5375 * const { Map } = require('immutable')
5376 * let obj = { 1: "one" };
5377 * Object.keys(obj); // [ "1" ]
5378 * assert.equal(obj["1"], obj[1]); // "one" === "one"
5379 *
5380 * let map = Map(obj);
5381 * assert.notEqual(map.get("1"), map.get(1)); // "one" !== undefined
5382 * ```
5383 *
5384 * Property access for JavaScript Objects first converts the key to a string,
5385 * but since Immutable Map keys can be of any type the argument to `get()` is
5386 * not altered.
5387 *
5388 * [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter
5389 * "Using the reviver parameter"
5390 * [2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects
5391 * "Working with array-like objects"
5392 * [3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol
5393 * "The iterable protocol"
5394 */
5395 function fromJS<JSValue>(
5396 jsValue: JSValue,
5397 reviver?: undefined
5398 ): FromJS<JSValue>;
5399 function fromJS(
5400 jsValue: unknown,
5401 reviver?: (
5402 key: string | number,
5403 sequence: Collection.Keyed<string, unknown> | Collection.Indexed<unknown>,
5404 path?: Array<string | number>
5405 ) => unknown
5406 ): Collection<unknown, unknown>;
5407
5408 type FromJS<JSValue> = JSValue extends FromJSNoTransform
5409 ? JSValue
5410 : JSValue extends Array<any>
5411 ? FromJSArray<JSValue>
5412 : JSValue extends {}
5413 ? FromJSObject<JSValue>
5414 : any;
5415
5416 type FromJSNoTransform =
5417 | Collection<any, any>
5418 | number
5419 | string
5420 | null
5421 | undefined;
5422
5423 type FromJSArray<JSValue> = JSValue extends Array<infer T>
5424 ? List<FromJS<T>>
5425 : never;
5426
5427 type FromJSObject<JSValue> = JSValue extends {}
5428 ? Map<keyof JSValue, FromJS<JSValue[keyof JSValue]>>
5429 : never;
5430
5431 /**
5432 * Value equality check with semantics similar to `Object.is`, but treats
5433 * Immutable `Collection`s as values, equal if the second `Collection` includes
5434 * equivalent values.
5435 *
5436 * It's used throughout Immutable when checking for equality, including `Map`
5437 * key equality and `Set` membership.
5438 *
5439 * <!-- runkit:activate -->
5440 * ```js
5441 * const { Map, is } = require('immutable')
5442 * const map1 = Map({ a: 1, b: 1, c: 1 })
5443 * const map2 = Map({ a: 1, b: 1, c: 1 })
5444 * assert.equal(map1 !== map2, true)
5445 * assert.equal(Object.is(map1, map2), false)
5446 * assert.equal(is(map1, map2), true)
5447 * ```
5448 *
5449 * `is()` compares primitive types like strings and numbers, Immutable.js
5450 * collections like `Map` and `List`, but also any custom object which
5451 * implements `ValueObject` by providing `equals()` and `hashCode()` methods.
5452 *
5453 * Note: Unlike `Object.is`, `Immutable.is` assumes `0` and `-0` are the same
5454 * value, matching the behavior of ES6 Map key equality.
5455 */
5456 function is(first: unknown, second: unknown): boolean;
5457
5458 /**
5459 * The `hash()` function is an important part of how Immutable determines if
5460 * two values are equivalent and is used to determine how to store those
5461 * values. Provided with any value, `hash()` will return a 31-bit integer.
5462 *
5463 * When designing Objects which may be equal, it's important that when a
5464 * `.equals()` method returns true, that both values `.hashCode()` method
5465 * return the same value. `hash()` may be used to produce those values.
5466 *
5467 * For non-Immutable Objects that do not provide a `.hashCode()` functions
5468 * (including plain Objects, plain Arrays, Date objects, etc), a unique hash
5469 * value will be created for each *instance*. That is, the create hash
5470 * represents referential equality, and not value equality for Objects. This
5471 * ensures that if that Object is mutated over time that its hash code will
5472 * remain consistent, allowing Objects to be used as keys and values in
5473 * Immutable.js collections.
5474 *
5475 * Note that `hash()` attempts to balance between speed and avoiding
5476 * collisions, however it makes no attempt to produce secure hashes.
5477 *
5478 * *New in Version 4.0*
5479 */
5480 function hash(value: unknown): number;
5481
5482 /**
5483 * True if `maybeImmutable` is an Immutable Collection or Record.
5484 *
5485 * Note: Still returns true even if the collections is within a `withMutations()`.
5486 *
5487 * <!-- runkit:activate -->
5488 * ```js
5489 * const { isImmutable, Map, List, Stack } = require('immutable');
5490 * isImmutable([]); // false
5491 * isImmutable({}); // false
5492 * isImmutable(Map()); // true
5493 * isImmutable(List()); // true
5494 * isImmutable(Stack()); // true
5495 * isImmutable(Map().asMutable()); // true
5496 * ```
5497 */
5498 function isImmutable(
5499 maybeImmutable: unknown
5500 ): maybeImmutable is Collection<unknown, unknown>;
5501
5502 /**
5503 * True if `maybeCollection` is a Collection, or any of its subclasses.
5504 *
5505 * <!-- runkit:activate -->
5506 * ```js
5507 * const { isCollection, Map, List, Stack } = require('immutable');
5508 * isCollection([]); // false
5509 * isCollection({}); // false
5510 * isCollection(Map()); // true
5511 * isCollection(List()); // true
5512 * isCollection(Stack()); // true
5513 * ```
5514 */
5515 function isCollection(
5516 maybeCollection: unknown
5517 ): maybeCollection is Collection<unknown, unknown>;
5518
5519 /**
5520 * True if `maybeKeyed` is a Collection.Keyed, or any of its subclasses.
5521 *
5522 * <!-- runkit:activate -->
5523 * ```js
5524 * const { isKeyed, Map, List, Stack } = require('immutable');
5525 * isKeyed([]); // false
5526 * isKeyed({}); // false
5527 * isKeyed(Map()); // true
5528 * isKeyed(List()); // false
5529 * isKeyed(Stack()); // false
5530 * ```
5531 */
5532 function isKeyed(
5533 maybeKeyed: unknown
5534 ): maybeKeyed is Collection.Keyed<unknown, unknown>;
5535
5536 /**
5537 * True if `maybeIndexed` is a Collection.Indexed, or any of its subclasses.
5538 *
5539 * <!-- runkit:activate -->
5540 * ```js
5541 * const { isIndexed, Map, List, Stack, Set } = require('immutable');
5542 * isIndexed([]); // false
5543 * isIndexed({}); // false
5544 * isIndexed(Map()); // false
5545 * isIndexed(List()); // true
5546 * isIndexed(Stack()); // true
5547 * isIndexed(Set()); // false
5548 * ```
5549 */
5550 function isIndexed(
5551 maybeIndexed: unknown
5552 ): maybeIndexed is Collection.Indexed<unknown>;
5553
5554 /**
5555 * True if `maybeAssociative` is either a Keyed or Indexed Collection.
5556 *
5557 * <!-- runkit:activate -->
5558 * ```js
5559 * const { isAssociative, Map, List, Stack, Set } = require('immutable');
5560 * isAssociative([]); // false
5561 * isAssociative({}); // false
5562 * isAssociative(Map()); // true
5563 * isAssociative(List()); // true
5564 * isAssociative(Stack()); // true
5565 * isAssociative(Set()); // false
5566 * ```
5567 */
5568 function isAssociative(
5569 maybeAssociative: unknown
5570 ): maybeAssociative is
5571 | Collection.Keyed<unknown, unknown>
5572 | Collection.Indexed<unknown>;
5573
5574 /**
5575 * True if `maybeOrdered` is a Collection where iteration order is well
5576 * defined. True for Collection.Indexed as well as OrderedMap and OrderedSet.
5577 *
5578 * <!-- runkit:activate -->
5579 * ```js
5580 * const { isOrdered, Map, OrderedMap, List, Set } = require('immutable');
5581 * isOrdered([]); // false
5582 * isOrdered({}); // false
5583 * isOrdered(Map()); // false
5584 * isOrdered(OrderedMap()); // true
5585 * isOrdered(List()); // true
5586 * isOrdered(Set()); // false
5587 * ```
5588 */
5589 function isOrdered(maybeOrdered: unknown): boolean;
5590
5591 /**
5592 * True if `maybeValue` is a JavaScript Object which has *both* `equals()`
5593 * and `hashCode()` methods.
5594 *
5595 * Any two instances of *value objects* can be compared for value equality with
5596 * `Immutable.is()` and can be used as keys in a `Map` or members in a `Set`.
5597 */
5598 function isValueObject(maybeValue: unknown): maybeValue is ValueObject;
5599
5600 /**
5601 * True if `maybeSeq` is a Seq.
5602 */
5603 function isSeq(
5604 maybeSeq: unknown
5605 ): maybeSeq is
5606 | Seq.Indexed<unknown>
5607 | Seq.Keyed<unknown, unknown>
5608 | Seq.Set<unknown>;
5609
5610 /**
5611 * True if `maybeList` is a List.
5612 */
5613 function isList(maybeList: unknown): maybeList is List<unknown>;
5614
5615 /**
5616 * True if `maybeMap` is a Map.
5617 *
5618 * Also true for OrderedMaps.
5619 */
5620 function isMap(maybeMap: unknown): maybeMap is Map<unknown, unknown>;
5621
5622 /**
5623 * True if `maybeOrderedMap` is an OrderedMap.
5624 */
5625 function isOrderedMap(
5626 maybeOrderedMap: unknown
5627 ): maybeOrderedMap is OrderedMap<unknown, unknown>;
5628
5629 /**
5630 * True if `maybeStack` is a Stack.
5631 */
5632 function isStack(maybeStack: unknown): maybeStack is Stack<unknown>;
5633
5634 /**
5635 * True if `maybeSet` is a Set.
5636 *
5637 * Also true for OrderedSets.
5638 */
5639 function isSet(maybeSet: unknown): maybeSet is Set<unknown>;
5640
5641 /**
5642 * True if `maybeOrderedSet` is an OrderedSet.
5643 */
5644 function isOrderedSet(
5645 maybeOrderedSet: unknown
5646 ): maybeOrderedSet is OrderedSet<unknown>;
5647
5648 /**
5649 * True if `maybeRecord` is a Record.
5650 */
5651 function isRecord(maybeRecord: unknown): maybeRecord is Record<{}>;
5652
5653 /**
5654 * Returns the value within the provided collection associated with the
5655 * provided key, or notSetValue if the key is not defined in the collection.
5656 *
5657 * A functional alternative to `collection.get(key)` which will also work on
5658 * plain Objects and Arrays as an alternative for `collection[key]`.
5659 *
5660 * <!-- runkit:activate -->
5661 * ```js
5662 * const { get } = require('immutable')
5663 * get([ 'dog', 'frog', 'cat' ], 2) // 'frog'
5664 * get({ x: 123, y: 456 }, 'x') // 123
5665 * get({ x: 123, y: 456 }, 'z', 'ifNotSet') // 'ifNotSet'
5666 * ```
5667 */
5668 function get<K, V>(collection: Collection<K, V>, key: K): V | undefined;
5669 function get<K, V, NSV>(
5670 collection: Collection<K, V>,
5671 key: K,
5672 notSetValue: NSV
5673 ): V | NSV;
5674 function get<TProps extends object, K extends keyof TProps>(
5675 record: Record<TProps>,
5676 key: K,
5677 notSetValue: unknown
5678 ): TProps[K];
5679 function get<V>(collection: Array<V>, key: number): V | undefined;
5680 function get<V, NSV>(
5681 collection: Array<V>,
5682 key: number,
5683 notSetValue: NSV
5684 ): V | NSV;
5685 function get<C extends object, K extends keyof C>(
5686 object: C,
5687 key: K,
5688 notSetValue: unknown
5689 ): C[K];
5690 function get<V>(collection: { [key: string]: V }, key: string): V | undefined;
5691 function get<V, NSV>(
5692 collection: { [key: string]: V },
5693 key: string,
5694 notSetValue: NSV
5695 ): V | NSV;
5696
5697 /**
5698 * Returns true if the key is defined in the provided collection.
5699 *
5700 * A functional alternative to `collection.has(key)` which will also work with
5701 * plain Objects and Arrays as an alternative for
5702 * `collection.hasOwnProperty(key)`.
5703 *
5704 * <!-- runkit:activate -->
5705 * ```js
5706 * const { has } = require('immutable')
5707 * has([ 'dog', 'frog', 'cat' ], 2) // true
5708 * has([ 'dog', 'frog', 'cat' ], 5) // false
5709 * has({ x: 123, y: 456 }, 'x') // true
5710 * has({ x: 123, y: 456 }, 'z') // false
5711 * ```
5712 */
5713 function has(collection: object, key: unknown): boolean;
5714
5715 /**
5716 * Returns a copy of the collection with the value at key removed.
5717 *
5718 * A functional alternative to `collection.remove(key)` which will also work
5719 * with plain Objects and Arrays as an alternative for
5720 * `delete collectionCopy[key]`.
5721 *
5722 * <!-- runkit:activate -->
5723 * ```js
5724 * const { remove } = require('immutable')
5725 * const originalArray = [ 'dog', 'frog', 'cat' ]
5726 * remove(originalArray, 1) // [ 'dog', 'cat' ]
5727 * console.log(originalArray) // [ 'dog', 'frog', 'cat' ]
5728 * const originalObject = { x: 123, y: 456 }
5729 * remove(originalObject, 'x') // { y: 456 }
5730 * console.log(originalObject) // { x: 123, y: 456 }
5731 * ```
5732 */
5733 function remove<K, C extends Collection<K, unknown>>(
5734 collection: C,
5735 key: K
5736 ): C;
5737 function remove<
5738 TProps extends object,
5739 C extends Record<TProps>,
5740 K extends keyof TProps
5741 >(collection: C, key: K): C;
5742 function remove<C extends Array<unknown>>(collection: C, key: number): C;
5743 function remove<C, K extends keyof C>(collection: C, key: K): C;
5744 function remove<C extends { [key: string]: unknown }, K extends keyof C>(
5745 collection: C,
5746 key: K
5747 ): C;
5748
5749 /**
5750 * Returns a copy of the collection with the value at key set to the provided
5751 * value.
5752 *
5753 * A functional alternative to `collection.set(key, value)` which will also
5754 * work with plain Objects and Arrays as an alternative for
5755 * `collectionCopy[key] = value`.
5756 *
5757 * <!-- runkit:activate -->
5758 * ```js
5759 * const { set } = require('immutable')
5760 * const originalArray = [ 'dog', 'frog', 'cat' ]
5761 * set(originalArray, 1, 'cow') // [ 'dog', 'cow', 'cat' ]
5762 * console.log(originalArray) // [ 'dog', 'frog', 'cat' ]
5763 * const originalObject = { x: 123, y: 456 }
5764 * set(originalObject, 'x', 789) // { x: 789, y: 456 }
5765 * console.log(originalObject) // { x: 123, y: 456 }
5766 * ```
5767 */
5768 function set<K, V, C extends Collection<K, V>>(
5769 collection: C,
5770 key: K,
5771 value: V
5772 ): C;
5773 function set<
5774 TProps extends object,
5775 C extends Record<TProps>,
5776 K extends keyof TProps
5777 >(record: C, key: K, value: TProps[K]): C;
5778 function set<V, C extends Array<V>>(collection: C, key: number, value: V): C;
5779 function set<C, K extends keyof C>(object: C, key: K, value: C[K]): C;
5780 function set<V, C extends { [key: string]: V }>(
5781 collection: C,
5782 key: string,
5783 value: V
5784 ): C;
5785
5786 /**
5787 * Returns a copy of the collection with the value at key set to the result of
5788 * providing the existing value to the updating function.
5789 *
5790 * A functional alternative to `collection.update(key, fn)` which will also
5791 * work with plain Objects and Arrays as an alternative for
5792 * `collectionCopy[key] = fn(collection[key])`.
5793 *
5794 * <!-- runkit:activate -->
5795 * ```js
5796 * const { update } = require('immutable')
5797 * const originalArray = [ 'dog', 'frog', 'cat' ]
5798 * update(originalArray, 1, val => val.toUpperCase()) // [ 'dog', 'FROG', 'cat' ]
5799 * console.log(originalArray) // [ 'dog', 'frog', 'cat' ]
5800 * const originalObject = { x: 123, y: 456 }
5801 * update(originalObject, 'x', val => val * 6) // { x: 738, y: 456 }
5802 * console.log(originalObject) // { x: 123, y: 456 }
5803 * ```
5804 */
5805 function update<K, V, C extends Collection<K, V>>(
5806 collection: C,
5807 key: K,
5808 updater: (value: V | undefined) => V | undefined
5809 ): C;
5810 function update<K, V, C extends Collection<K, V>, NSV>(
5811 collection: C,
5812 key: K,
5813 notSetValue: NSV,
5814 updater: (value: V | NSV) => V
5815 ): C;
5816 function update<
5817 TProps extends object,
5818 C extends Record<TProps>,
5819 K extends keyof TProps
5820 >(record: C, key: K, updater: (value: TProps[K]) => TProps[K]): C;
5821 function update<
5822 TProps extends object,
5823 C extends Record<TProps>,
5824 K extends keyof TProps,
5825 NSV
5826 >(
5827 record: C,
5828 key: K,
5829 notSetValue: NSV,
5830 updater: (value: TProps[K] | NSV) => TProps[K]
5831 ): C;
5832 function update<V>(
5833 collection: Array<V>,
5834 key: number,
5835 updater: (value: V | undefined) => V | undefined
5836 ): Array<V>;
5837 function update<V, NSV>(
5838 collection: Array<V>,
5839 key: number,
5840 notSetValue: NSV,
5841 updater: (value: V | NSV) => V
5842 ): Array<V>;
5843 function update<C, K extends keyof C>(
5844 object: C,
5845 key: K,
5846 updater: (value: C[K]) => C[K]
5847 ): C;
5848 function update<C, K extends keyof C, NSV>(
5849 object: C,
5850 key: K,
5851 notSetValue: NSV,
5852 updater: (value: C[K] | NSV) => C[K]
5853 ): C;
5854 function update<V, C extends { [key: string]: V }, K extends keyof C>(
5855 collection: C,
5856 key: K,
5857 updater: (value: V) => V
5858 ): { [key: string]: V };
5859 function update<V, C extends { [key: string]: V }, K extends keyof C, NSV>(
5860 collection: C,
5861 key: K,
5862 notSetValue: NSV,
5863 updater: (value: V | NSV) => V
5864 ): { [key: string]: V };
5865
5866 /**
5867 * Returns the value at the provided key path starting at the provided
5868 * collection, or notSetValue if the key path is not defined.
5869 *
5870 * A functional alternative to `collection.getIn(keypath)` which will also
5871 * work with plain Objects and Arrays.
5872 *
5873 * <!-- runkit:activate -->
5874 * ```js
5875 * const { getIn } = require('immutable')
5876 * getIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // 123
5877 * getIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p'], 'ifNotSet') // 'ifNotSet'
5878 * ```
5879 */
5880 function getIn(
5881 collection: unknown,
5882 keyPath: Iterable<unknown>,
5883 notSetValue?: unknown
5884 ): unknown;
5885
5886 /**
5887 * Returns true if the key path is defined in the provided collection.
5888 *
5889 * A functional alternative to `collection.hasIn(keypath)` which will also
5890 * work with plain Objects and Arrays.
5891 *
5892 * <!-- runkit:activate -->
5893 * ```js
5894 * const { hasIn } = require('immutable')
5895 * hasIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // true
5896 * hasIn({ x: { y: { z: 123 }}}, ['x', 'q', 'p']) // false
5897 * ```
5898 */
5899 function hasIn(collection: unknown, keyPath: Iterable<unknown>): boolean;
5900
5901 /**
5902 * Returns a copy of the collection with the value at the key path removed.
5903 *
5904 * A functional alternative to `collection.removeIn(keypath)` which will also
5905 * work with plain Objects and Arrays.
5906 *
5907 * <!-- runkit:activate -->
5908 * ```js
5909 * const { removeIn } = require('immutable')
5910 * const original = { x: { y: { z: 123 }}}
5911 * removeIn(original, ['x', 'y', 'z']) // { x: { y: {}}}
5912 * console.log(original) // { x: { y: { z: 123 }}}
5913 * ```
5914 */
5915 function removeIn<C>(collection: C, keyPath: Iterable<unknown>): C;
5916
5917 /**
5918 * Returns a copy of the collection with the value at the key path set to the
5919 * provided value.
5920 *
5921 * A functional alternative to `collection.setIn(keypath)` which will also
5922 * work with plain Objects and Arrays.
5923 *
5924 * <!-- runkit:activate -->
5925 * ```js
5926 * const { setIn } = require('immutable')
5927 * const original = { x: { y: { z: 123 }}}
5928 * setIn(original, ['x', 'y', 'z'], 456) // { x: { y: { z: 456 }}}
5929 * console.log(original) // { x: { y: { z: 123 }}}
5930 * ```
5931 */
5932 function setIn<C>(
5933 collection: C,
5934 keyPath: Iterable<unknown>,
5935 value: unknown
5936 ): C;
5937
5938 /**
5939 * Returns a copy of the collection with the value at key path set to the
5940 * result of providing the existing value to the updating function.
5941 *
5942 * A functional alternative to `collection.updateIn(keypath)` which will also
5943 * work with plain Objects and Arrays.
5944 *
5945 * <!-- runkit:activate -->
5946 * ```js
5947 * const { updateIn } = require('immutable')
5948 * const original = { x: { y: { z: 123 }}}
5949 * updateIn(original, ['x', 'y', 'z'], val => val * 6) // { x: { y: { z: 738 }}}
5950 * console.log(original) // { x: { y: { z: 123 }}}
5951 * ```
5952 */
5953 function updateIn<C>(
5954 collection: C,
5955 keyPath: Iterable<unknown>,
5956 updater: (value: unknown) => unknown
5957 ): C;
5958 function updateIn<C>(
5959 collection: C,
5960 keyPath: Iterable<unknown>,
5961 notSetValue: unknown,
5962 updater: (value: unknown) => unknown
5963 ): C;
5964
5965 /**
5966 * Returns a copy of the collection with the remaining collections merged in.
5967 *
5968 * A functional alternative to `collection.merge()` which will also work with
5969 * plain Objects and Arrays.
5970 *
5971 * <!-- runkit:activate -->
5972 * ```js
5973 * const { merge } = require('immutable')
5974 * const original = { x: 123, y: 456 }
5975 * merge(original, { y: 789, z: 'abc' }) // { x: 123, y: 789, z: 'abc' }
5976 * console.log(original) // { x: 123, y: 456 }
5977 * ```
5978 */
5979 function merge<C>(
5980 collection: C,
5981 ...collections: Array<
5982 | Iterable<unknown>
5983 | Iterable<[unknown, unknown]>
5984 | { [key: string]: unknown }
5985 >
5986 ): C;
5987
5988 /**
5989 * Returns a copy of the collection with the remaining collections merged in,
5990 * calling the `merger` function whenever an existing value is encountered.
5991 *
5992 * A functional alternative to `collection.mergeWith()` which will also work
5993 * with plain Objects and Arrays.
5994 *
5995 * <!-- runkit:activate -->
5996 * ```js
5997 * const { mergeWith } = require('immutable')
5998 * const original = { x: 123, y: 456 }
5999 * mergeWith(
6000 * (oldVal, newVal) => oldVal + newVal,
6001 * original,
6002 * { y: 789, z: 'abc' }
6003 * ) // { x: 123, y: 1245, z: 'abc' }
6004 * console.log(original) // { x: 123, y: 456 }
6005 * ```
6006 */
6007 function mergeWith<C>(
6008 merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown,
6009 collection: C,
6010 ...collections: Array<
6011 | Iterable<unknown>
6012 | Iterable<[unknown, unknown]>
6013 | { [key: string]: unknown }
6014 >
6015 ): C;
6016
6017 /**
6018 * Like `merge()`, but when two compatible collections are encountered with
6019 * the same key, it merges them as well, recursing deeply through the nested
6020 * data. Two collections are considered to be compatible (and thus will be
6021 * merged together) if they both fall into one of three categories: keyed
6022 * (e.g., `Map`s, `Record`s, and objects), indexed (e.g., `List`s and
6023 * arrays), or set-like (e.g., `Set`s). If they fall into separate
6024 * categories, `mergeDeep` will replace the existing collection with the
6025 * collection being merged in. This behavior can be customized by using
6026 * `mergeDeepWith()`.
6027 *
6028 * Note: Indexed and set-like collections are merged using
6029 * `concat()`/`union()` and therefore do not recurse.
6030 *
6031 * A functional alternative to `collection.mergeDeep()` which will also work
6032 * with plain Objects and Arrays.
6033 *
6034 * <!-- runkit:activate -->
6035 * ```js
6036 * const { mergeDeep } = require('immutable')
6037 * const original = { x: { y: 123 }}
6038 * mergeDeep(original, { x: { z: 456 }}) // { x: { y: 123, z: 456 }}
6039 * console.log(original) // { x: { y: 123 }}
6040 * ```
6041 */
6042 function mergeDeep<C>(
6043 collection: C,
6044 ...collections: Array<
6045 | Iterable<unknown>
6046 | Iterable<[unknown, unknown]>
6047 | { [key: string]: unknown }
6048 >
6049 ): C;
6050
6051 /**
6052 * Like `mergeDeep()`, but when two non-collections or incompatible
6053 * collections are encountered at the same key, it uses the `merger` function
6054 * to determine the resulting value. Collections are considered incompatible
6055 * if they fall into separate categories between keyed, indexed, and set-like.
6056 *
6057 * A functional alternative to `collection.mergeDeepWith()` which will also
6058 * work with plain Objects and Arrays.
6059 *
6060 * <!-- runkit:activate -->
6061 * ```js
6062 * const { mergeDeepWith } = require('immutable')
6063 * const original = { x: { y: 123 }}
6064 * mergeDeepWith(
6065 * (oldVal, newVal) => oldVal + newVal,
6066 * original,
6067 * { x: { y: 456 }}
6068 * ) // { x: { y: 579 }}
6069 * console.log(original) // { x: { y: 123 }}
6070 * ```
6071 */
6072 function mergeDeepWith<C>(
6073 merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown,
6074 collection: C,
6075 ...collections: Array<
6076 | Iterable<unknown>
6077 | Iterable<[unknown, unknown]>
6078 | { [key: string]: unknown }
6079 >
6080 ): C;
6081}
6082
6083/**
6084 * Defines the main export of the immutable module to be the Immutable namespace
6085 * This supports many common module import patterns:
6086 *
6087 * const Immutable = require("immutable");
6088 * const { List } = require("immutable");
6089 * import Immutable from "immutable";
6090 * import * as Immutable from "immutable";
6091 * import { List } from "immutable";
6092 *
6093 */
6094export = Immutable;
6095
6096/**
6097 * A global "Immutable" namespace used by UMD modules which allows the use of
6098 * the full Immutable API.
6099 *
6100 * If using Immutable as an imported module, prefer using:
6101 *
6102 * import Immutable from 'immutable'
6103 *
6104 */
6105export as namespace Immutable;
6106
\No newline at end of file