or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

collections.mdfunctional-api.mdindex.mdsequences.mdutilities.md
tile.json

collections.mddocs/

Collections

Overview

Immutable.js provides persistent immutable data structures that use structural sharing for efficient memory usage and performance. All collections implement value equality semantics and provide a rich API for functional data manipulation.

Core Imports

import { List, Map, OrderedMap, Set, OrderedSet, Stack } from 'immutable';

Base Collection Interface

All collections implement the base Collection interface:

interface Collection<K, V> {
  // Properties
  size: number;
  
  // Value equality
  equals(other: unknown): boolean;
  hashCode(): number;
  
  // Reading values
  get(key: K, notSetValue?: V): V | undefined;
  has(key: K): boolean;
  includes(value: V): boolean;
  first(notSetValue?: V): V | undefined;
  last(notSetValue?: V): V | undefined;
  
  // Deep operations
  getIn(keyPath: Iterable<unknown>, notSetValue?: unknown): unknown;
  hasIn(keyPath: Iterable<unknown>): boolean;
  setIn(keyPath: Iterable<unknown>, value: unknown): this;
  updateIn(keyPath: Iterable<unknown>, updater: (value: unknown) => unknown): this;
  deleteIn(keyPath: Iterable<unknown>): this;
  mergeIn(keyPath: Iterable<unknown>, ...collections: unknown[]): this;
  mergeDeepIn(keyPath: Iterable<unknown>, ...collections: unknown[]): this;
  
  // Conversion
  toJS(): unknown;
  toJSON(): unknown;
  toArray(): unknown[];
  toObject(): { [key: string]: V };
  toMap(): Map<K, V>;
  toOrderedMap(): OrderedMap<K, V>;
  toSet(): Set<V>;
  toOrderedSet(): OrderedSet<V>;
  toList(): List<V>;
  toStack(): Stack<V>;
  toSeq(): Seq<K, V>;
  toKeyedSeq(): Seq.Keyed<K, V>;
  toIndexedSeq(): Seq.Indexed<V>;
  toSetSeq(): Seq.Set<V>;
  
  // Iterators
  keys(): IterableIterator<K>;
  values(): IterableIterator<V>;
  entries(): IterableIterator<[K, V]>;
  [Symbol.iterator](): IterableIterator<[K, V]>;
  
  // Sequences
  keySeq(): Seq.Indexed<K>;
  valueSeq(): Seq.Indexed<V>;
  entrySeq(): Seq.Indexed<[K, V]>;
  
  // Sequence operations
  map<M>(mapper: (value: V, key: K, iter: this) => M, context?: unknown): Collection<K, M>;
  filter(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
  filterNot(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
  partition(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): [this, this];
  reverse(): this;
  sort(comparator?: Comparator<V>): this;
  sortBy<C>(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: Comparator<C>): this;
  groupBy<G>(grouper: (value: V, key: K, iter: this) => G, context?: unknown): Map<G, this>;
  
  // Side effects
  forEach(sideEffect: (value: V, key: K, iter: this) => void, context?: unknown): number;
  
  // Creating subsets
  slice(begin?: number, end?: number): this;
  rest(): this;
  butLast(): this;
  skip(amount: number): this;
  skipLast(amount: number): this;
  skipWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
  skipUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
  take(amount: number): this;
  takeLast(amount: number): this;
  takeWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
  takeUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
  
  // Combination
  concat(...valuesOrCollections: Array<unknown>): this;
  flatten(depth?: number): Collection<unknown, unknown>;
  flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: unknown): Collection<number, M>;
  
  // Reducing
  reduce<R>(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: unknown): R;
  reduceRight<R>(reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: unknown): R;
  every(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): boolean;
  some(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): boolean;
  join(separator?: string): string;
  isEmpty(): boolean;
  count(predicate?: (value: V, key: K, iter: this) => boolean, context?: unknown): number;
  countBy<G>(grouper: (value: V, key: K, iter: this) => G, context?: unknown): Map<G, number>;
  
  // Search
  find(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown, notSetValue?: V): V | undefined;
  findLast(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown, notSetValue?: V): V | undefined;
  findEntry(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown, notSetValue?: V): [K, V] | undefined;
  findLastEntry(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown, notSetValue?: V): [K, V] | undefined;
  findKey(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): K | undefined;
  findLastKey(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): K | undefined;
  keyOf(searchValue: V): K | undefined;
  lastKeyOf(searchValue: V): K | undefined;
  max(comparator?: Comparator<V>): V | undefined;
  maxBy<C>(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: Comparator<C>): V | undefined;
  min(comparator?: Comparator<V>): V | undefined;
  minBy<C>(comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: Comparator<C>): V | undefined;
  
  // Comparison
  isSubset(iter: Iterable<V>): boolean;
  isSuperset(iter: Iterable<V>): boolean;
  
  // Transient operations
  withMutations(mutator: (mutable: this) => unknown): this;
  asMutable(): this;
  asImmutable(): this;
  wasAltered(): boolean;
}

List

Ordered indexed dense collection, similar to JavaScript Array.

class List<T> implements Collection<number, T> {
  // Factory methods
  static <T>(collection?: Iterable<T>): List<T>;
  static of<T>(...values: T[]): List<T>;
  static isList(maybeList: unknown): maybeList is List<unknown>;
  
  // Properties
  size: number;
  
  // Reading values
  get(index: number, notSetValue?: T): T | undefined;
  has(index: number): boolean;
  includes(value: T): boolean;
  first(notSetValue?: T): T | undefined;
  last(notSetValue?: T): T | undefined;
  
  // Persistent changes
  set(index: number, value: T): List<T>;
  delete(index: number): List<T>;
  remove(index: number): List<T>;
  insert(index: number, value: T): List<T>;
  clear(): List<T>;
  push(...values: T[]): List<T>;
  pop(): List<T>;
  unshift(...values: T[]): List<T>;
  shift(): List<T>;
  update(index: number, updater: (value: T) => T): List<T>;
  update(index: number, notSetValue: T, updater: (value: T) => T): List<T>;
  update(updater: (value: List<T>) => List<T>): List<T>;
  setSize(size: number): List<T>;
  
  // Sequence operations
  concat(...valuesOrCollections: Array<T | Iterable<T>>): List<T>;
  map<M>(mapper: (value: T, index: number, iter: List<T>) => M, context?: unknown): List<M>;
  flatMap<M>(mapper: (value: T, index: number, iter: List<T>) => Iterable<M>, context?: unknown): List<M>;
  filter(predicate: (value: T, index: number, iter: List<T>) => boolean, context?: unknown): List<T>;
  partition(predicate: (value: T, index: number, iter: List<T>) => boolean, context?: unknown): [List<T>, List<T>];
  zip<U>(other: Collection<number, U>): List<[T, U]>;
  zipAll<U>(other: Collection<number, U>): List<[T, U]>;
  zipWith<U, Z>(zipper: (value: T, otherValue: U) => Z, otherCollection: Collection<number, U>): List<Z>;
}

Usage Examples

import { List } from 'immutable';

// Creating Lists
const list1 = List([1, 2, 3]);
const list2 = List.of(1, 2, 3);

// Reading values
console.log(list1.get(0)); // 1
console.log(list1.first()); // 1
console.log(list1.last()); // 3

// Persistent modifications
const list3 = list1.push(4, 5); // [1, 2, 3, 4, 5]
const list4 = list1.set(1, 'two'); // [1, 'two', 3]
const list5 = list1.insert(1, 'new'); // [1, 'new', 2, 3]

// Sequence operations
const doubled = list1.map(x => x * 2); // [2, 4, 6]
const filtered = list1.filter(x => x > 1); // [2, 3]

Map

Unordered keyed collection, similar to JavaScript Object or ES6 Map.

class Map<K, V> implements Collection<K, V> {
  // Factory methods
  static <K, V>(collection?: Iterable<[K, V]> | ArrayLike<[K, V]> | {[key: string]: V}): Map<K, V>;
  static isMap(maybeMap: unknown): maybeMap is Map<unknown, unknown>;
  
  // Properties
  size: number;
  
  // Reading values
  get(key: K, notSetValue?: V): V | undefined;
  has(key: K): boolean;
  includes(value: V): boolean;
  first(notSetValue?: V): V | undefined;
  last(notSetValue?: V): V | undefined;
  
  // Persistent changes
  set(key: K, value: V): Map<K, V>;
  delete(key: K): Map<K, V>;
  remove(key: K): Map<K, V>;
  deleteAll(keys: Iterable<K>): Map<K, V>;
  removeAll(keys: Iterable<K>): Map<K, V>;
  clear(): Map<K, V>;
  update(key: K, updater: (value: V) => V): Map<K, V>;
  update(key: K, notSetValue: V, updater: (value: V) => V): Map<K, V>;
  update(updater: (value: Map<K, V>) => Map<K, V>): Map<K, V>;
  merge(...collections: Array<Iterable<[K, V]> | {[key: string]: V}>): Map<K, V>;
  mergeWith(merger: (oldVal: V, newVal: V, key: K) => V, ...collections: Array<Iterable<[K, V]> | {[key: string]: V}>): Map<K, V>;
  mergeDeep(...collections: Array<Iterable<[K, V]> | {[key: string]: V}>): Map<K, V>;
  mergeDeepWith(merger: (oldVal: unknown, newVal: unknown, key: unknown) => unknown, ...collections: Array<Iterable<[K, V]> | {[key: string]: V}>): Map<K, V>;
  
  // Sequence operations
  concat(...collections: Array<Iterable<[K, V]> | {[key: string]: V}>): Map<K, V>;
  map<M>(mapper: (value: V, key: K, iter: Map<K, V>) => M, context?: unknown): Map<K, M>;
  mapKeys<M>(mapper: (key: K, value: V, iter: Map<K, V>) => M, context?: unknown): Map<M, V>;
  mapEntries<KM, VM>(mapper: (entry: [K, V], index: number, iter: Map<K, V>) => [KM, VM], context?: unknown): Map<KM, VM>;
  flatMap<KM, VM>(mapper: (value: V, key: K, iter: Map<K, V>) => Iterable<[KM, VM]>, context?: unknown): Map<KM, VM>;
  filter(predicate: (value: V, key: K, iter: Map<K, V>) => boolean, context?: unknown): Map<K, V>;
  partition(predicate: (value: V, key: K, iter: Map<K, V>) => boolean, context?: unknown): [Map<K, V>, Map<K, V>];
  flip(): Map<V, K>;
}

Usage Examples

import { Map } from 'immutable';

// Creating Maps
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = Map([['a', 1], ['b', 2], ['c', 3]]);

// Reading values
console.log(map1.get('a')); // 1
console.log(map1.has('b')); // true

// Persistent modifications
const map3 = map1.set('d', 4); // { a: 1, b: 2, c: 3, d: 4 }
const map4 = map1.delete('b'); // { a: 1, c: 3 }
const map5 = map1.merge({ d: 4, e: 5 }); // { a: 1, b: 2, c: 3, d: 4, e: 5 }

// Sequence operations
const doubled = map1.map(x => x * 2); // { a: 2, b: 4, c: 6 }
const filtered = map1.filter(x => x > 1); // { b: 2, c: 3 }
const flipped = map1.flip(); // { 1: 'a', 2: 'b', 3: 'c' }

OrderedMap

Ordered keyed collection that maintains insertion order.

class OrderedMap<K, V> implements Collection<K, V> {
  // Factory methods
  static <K, V>(collection?: Iterable<[K, V]> | ArrayLike<[K, V]> | {[key: string]: V}): OrderedMap<K, V>;
  static isOrderedMap(maybeOrderedMap: unknown): maybeOrderedMap is OrderedMap<unknown, unknown>;
  
  // All Map methods with order preservation
  set(key: K, value: V): OrderedMap<K, V>;
  merge(...collections: Array<Iterable<[K, V]> | {[key: string]: V}>): OrderedMap<K, V>;
  concat(...collections: Array<Iterable<[K, V]> | {[key: string]: V}>): OrderedMap<K, V>;
  map<M>(mapper: (value: V, key: K, iter: OrderedMap<K, V>) => M, context?: unknown): OrderedMap<K, M>;
  mapKeys<M>(mapper: (key: K, value: V, iter: OrderedMap<K, V>) => M, context?: unknown): OrderedMap<M, V>;
  mapEntries<KM, VM>(mapper: (entry: [K, V], index: number, iter: OrderedMap<K, V>) => [KM, VM], context?: unknown): OrderedMap<KM, VM>;
  flatMap<KM, VM>(mapper: (value: V, key: K, iter: OrderedMap<K, V>) => Iterable<[KM, VM]>, context?: unknown): OrderedMap<KM, VM>;
  filter(predicate: (value: V, key: K, iter: OrderedMap<K, V>) => boolean, context?: unknown): OrderedMap<K, V>;
  partition(predicate: (value: V, key: K, iter: OrderedMap<K, V>) => boolean, context?: unknown): [OrderedMap<K, V>, OrderedMap<K, V>];
  flip(): OrderedMap<V, K>;
}

Set

Unordered collection of unique values.

class Set<T> implements Collection<T, T> {
  // Factory methods
  static <T>(collection?: Iterable<T>): Set<T>;
  static of<T>(...values: T[]): Set<T>;
  static fromKeys<T>(iter: Collection<T, unknown>): Set<T>;
  static intersect<T>(sets: Iterable<Iterable<T>>): Set<T>;
  static union<T>(sets: Iterable<Iterable<T>>): Set<T>;
  static isSet(maybeSet: unknown): maybeSet is Set<unknown>;
  
  // Properties
  size: number;
  
  // Reading values
  has(value: T): boolean;
  includes(value: T): boolean;
  first(notSetValue?: T): T | undefined;
  last(notSetValue?: T): T | undefined;
  
  // Persistent changes
  add(value: T): Set<T>;
  delete(value: T): Set<T>;
  remove(value: T): Set<T>;
  clear(): Set<T>;
  union(...collections: Iterable<T>[]): Set<T>;
  merge(...collections: Iterable<T>[]): Set<T>;
  intersect(...collections: Iterable<T>[]): Set<T>;
  subtract(...collections: Iterable<T>[]): Set<T>;
  
  // Sequence operations
  concat(...valuesOrCollections: Array<T | Iterable<T>>): Set<T>;
  map<M>(mapper: (value: T, value2: T, iter: Set<T>) => M, context?: unknown): Set<M>;
  flatMap<M>(mapper: (value: T, value2: T, iter: Set<T>) => Iterable<M>, context?: unknown): Set<M>;
  filter(predicate: (value: T, value2: T, iter: Set<T>) => boolean, context?: unknown): Set<T>;
  partition(predicate: (value: T, value2: T, iter: Set<T>) => boolean, context?: unknown): [Set<T>, Set<T>];
}

Usage Examples

import { Set } from 'immutable';

// Creating Sets
const set1 = Set([1, 2, 3, 2]); // [1, 2, 3]
const set2 = Set.of(1, 2, 3);

// Reading values
console.log(set1.has(2)); // true
console.log(set1.includes(4)); // false

// Persistent modifications
const set3 = set1.add(4); // [1, 2, 3, 4]
const set4 = set1.delete(2); // [1, 3]

// Set operations
const set5 = Set([1, 2, 3]);
const set6 = Set([2, 3, 4]);
const union = set5.union(set6); // [1, 2, 3, 4]
const intersection = set5.intersect(set6); // [2, 3]
const difference = set5.subtract(set6); // [1]

OrderedSet

Ordered collection of unique values that maintains insertion order.

class OrderedSet<T> implements Collection<T, T> {
  // Factory methods
  static <T>(collection?: Iterable<T>): OrderedSet<T>;
  static of<T>(...values: T[]): OrderedSet<T>;
  static fromKeys<T>(iter: Collection<T, unknown>): OrderedSet<T>;
  static isOrderedSet(maybeOrderedSet: unknown): maybeOrderedSet is OrderedSet<unknown>;
  
  // All Set methods with order preservation
  add(value: T): OrderedSet<T>;
  union(...collections: Iterable<T>[]): OrderedSet<T>;
  merge(...collections: Iterable<T>[]): OrderedSet<T>;
  concat(...valuesOrCollections: Array<T | Iterable<T>>): OrderedSet<T>;
  map<M>(mapper: (value: T, value2: T, iter: OrderedSet<T>) => M, context?: unknown): OrderedSet<M>;
  flatMap<M>(mapper: (value: T, value2: T, iter: OrderedSet<T>) => Iterable<M>, context?: unknown): OrderedSet<M>;
  filter(predicate: (value: T, value2: T, iter: OrderedSet<T>) => boolean, context?: unknown): OrderedSet<T>;
  partition(predicate: (value: T, value2: T, iter: OrderedSet<T>) => boolean, context?: unknown): [OrderedSet<T>, OrderedSet<T>];
  zip<U>(other: Collection<unknown, U>): OrderedSet<[T, U]>;
  zipAll<U>(other: Collection<unknown, U>): OrderedSet<[T, U]>;
  zipWith<U, Z>(zipper: (value: T, otherValue: U) => Z, otherCollection: Collection<unknown, U>): OrderedSet<Z>;
}

Stack

Stack/LIFO collection optimized for adding and removing from the front.

class Stack<T> implements Collection<number, T> {
  // Factory methods
  static <T>(collection?: Iterable<T>): Stack<T>;
  static of<T>(...values: T[]): Stack<T>;
  static isStack(maybeStack: unknown): maybeStack is Stack<unknown>;
  
  // Properties
  size: number;
  
  // Reading values
  get(index: number, notSetValue?: T): T | undefined;
  has(index: number): boolean;
  includes(value: T): boolean;
  first(notSetValue?: T): T | undefined;
  last(notSetValue?: T): T | undefined;
  peek(): T | undefined; // Alias for first()
  
  // Persistent changes (optimized for front operations)
  clear(): Stack<T>;
  unshift(...values: T[]): Stack<T>; // Add to front (efficient)
  push(...values: T[]): Stack<T>; // Alias for unshift
  unshiftAll(iter: Iterable<T>): Stack<T>;
  pushAll(iter: Iterable<T>): Stack<T>;
  shift(): Stack<T>; // Remove from front (efficient)
  pop(): Stack<T>; // Alias for shift
  
  // Sequence operations
  concat(...valuesOrCollections: Array<T | Iterable<T>>): Stack<T>;
  map<M>(mapper: (value: T, index: number, iter: Stack<T>) => M, context?: unknown): Stack<M>;
  flatMap<M>(mapper: (value: T, index: number, iter: Stack<T>) => Iterable<M>, context?: unknown): Stack<M>;
  filter(predicate: (value: T, index: number, iter: Stack<T>) => boolean, context?: unknown): Stack<T>;
  zip<U>(other: Collection<number, U>): Stack<[T, U]>;
  zipAll<U>(other: Collection<number, U>): Stack<[T, U]>;
  zipWith<U, Z>(zipper: (value: T, otherValue: U) => Z, otherCollection: Collection<number, U>): Stack<Z>;
}

Usage Examples

import { Stack } from 'immutable';

// Creating Stacks
const stack1 = Stack([1, 2, 3]); // Front: [1, 2, 3] :Back
const stack2 = Stack.of(1, 2, 3);

// Reading values (front is index 0)
console.log(stack1.peek()); // 1
console.log(stack1.first()); // 1

// Efficient front operations
const stack3 = stack1.push(0); // [0, 1, 2, 3]
const stack4 = stack1.pop(); // [2, 3]

// Multiple values
const stack5 = stack1.push(0, -1); // [-1, 0, 1, 2, 3]

Transient Operations

All collections support transient operations for performance optimization when making many changes:

interface Collection<K, V> {
  withMutations(mutator: (mutable: this) => unknown): this;
  asMutable(): this;
  asImmutable(): this;
  wasAltered(): boolean;
}

Usage Examples

import { List } from 'immutable';

// Efficient batch operations
const list = List([1, 2, 3]);
const newList = list.withMutations(mutable => {
  mutable.push(4).push(5).push(6);
  return mutable.set(0, 10);
}); // [10, 2, 3, 4, 5, 6]

// Manual transient operations
const mutableList = list.asMutable();
mutableList.push(4);
mutableList.push(5);
const finalList = mutableList.asImmutable(); // [1, 2, 3, 4, 5]