/** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * This file provides type definitions for use with the Flow type checker. * * An important caveat when using these definitions is that the types for * `Iterable.Keyed`, `Iterable.Indexed`, `Seq.Keyed`, and so on are stubs. * When referring to those types, you can get the proper definitions by * importing the types `KeyedIterable`, `IndexedIterable`, `KeyedSeq`, etc. * For example, * * import { Seq } from 'immutable' * import type { IndexedIterable, IndexedSeq } from 'immutable' * * const someSeq: IndexedSeq = Seq.Indexed.of(1, 2, 3) * * function takesASeq>(iter: TS): TS { * return iter.butLast() * } * * takesASeq(someSeq) * * @flow */ /* * Alias for ECMAScript `Iterable` type, declared in * https://github.com/facebook/flow/blob/master/lib/core.js * * Note that Immutable values implement the `ESIterable` interface. */ type ESIterable = $Iterable; declare class Iterable extends _Iterable {} declare class _Iterable { static Keyed: KI; static Indexed: II; static Set: SI; static isIterable(maybeIterable: any): boolean; static isKeyed(maybeKeyed: any): boolean; static isIndexed(maybeIndexed: any): boolean; static isAssociative(maybeAssociative: any): boolean; static isOrdered(maybeOrdered: any): boolean; equals(other: Iterable): boolean; hashCode(): number; get(key: K): V; get(key: K, notSetValue: V_): V|V_; has(key: K): boolean; includes(value: V): boolean; contains(value: V): boolean; first(): V; last(): V; getIn(searchKeyPath: ESIterable, notSetValue: T): T; getIn(searchKeyPath: ESIterable): T; hasIn(searchKeyPath: ESIterable): boolean; toJS(): any; toArray(): V[]; toObject(): { [key: string]: V }; toMap(): Map; toOrderedMap(): Map; toSet(): Set; toOrderedSet(): Set; toList(): List; toStack(): Stack; toSeq(): Seq; toKeyedSeq(): KeyedSeq; toIndexedSeq(): IndexedSeq; toSetSeq(): SetSeq; keys(): Iterator; values(): Iterator; entries(): Iterator<[K,V]>; keySeq(): IndexedSeq; valueSeq(): IndexedSeq; entrySeq(): IndexedSeq<[K,V]>; reverse(): this; sort(comparator?: (valueA: V, valueB: V) => number): this; sortBy( comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number ): this; groupBy( grouper: (value: V, key: K, iter: this) => G, context?: any ): KeyedSeq; forEach( sideEffect: (value: V, key: K, iter: this) => any, context?: any ): number; 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) => mixed, context?: any): this; skipUntil(predicate: (value: V, key: K, iter: this) => mixed, context?: any): this; take(amount: number): this; takeLast(amount: number): this; takeWhile(predicate: (value: V, key: K, iter: this) => mixed, context?: any): this; takeUntil(predicate: (value: V, key: K, iter: this) => mixed, context?: any): this; flatten(depth?: number): /*this*/Iterable; flatten(shallow?: boolean): /*this*/Iterable; filter( predicate: (value: V, key: K, iter: this) => mixed, context?: any ): this; filterNot( predicate: (value: V, key: K, iter: this) => mixed, context?: any ): this; reduce( reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction?: R, context?: any, ): R; reduceRight( reducer: (reduction: R, value: V, key: K, iter: this) => R, initialReduction?: R, context?: any, ): R; every(predicate: (value: V, key: K, iter: this) => mixed, context?: any): boolean; some(predicate: (value: V, key: K, iter: this) => mixed, context?: any): boolean; join(separator?: string): string; isEmpty(): boolean; count(predicate?: (value: V, key: K, iter: this) => mixed, context?: any): number; countBy(grouper: (value: V, key: K, iter: this) => G, context?: any): Map; find( predicate: (value: V, key: K, iter: this) => mixed, context?: any, ): ?V; find( predicate: (value: V, key: K, iter: this) => mixed, context: any, notSetValue: V_ ): V|V_; findLast( predicate: (value: V, key: K, iter: this) => mixed, context?: any, ): ?V; findLast( predicate: (value: V, key: K, iter: this) => mixed, context: any, notSetValue: V_ ): V|V_; findEntry(predicate: (value: V, key: K, iter: this) => mixed): ?[K,V]; findLastEntry(predicate: (value: V, key: K, iter: this) => mixed): ?[K,V]; findKey(predicate: (value: V, key: K, iter: this) => mixed, context?: any): ?K; findLastKey(predicate: (value: V, key: K, iter: this) => mixed, context?: any): ?K; keyOf(searchValue: V): ?K; lastKeyOf(searchValue: V): ?K; max(comparator?: (valueA: V, valueB: V) => number): V; maxBy( comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number ): V; min(comparator?: (valueA: V, valueB: V) => number): V; minBy( comparatorValueMapper: (value: V, key: K, iter: this) => C, comparator?: (valueA: C, valueB: C) => number ): V; isSubset(iter: Iterable): boolean; isSubset(iter: ESIterable): boolean; isSuperset(iter: Iterable): boolean; isSuperset(iter: ESIterable): boolean; } declare class KeyedIterable extends Iterable { static (iter?: ESIterable<[K,V]>): KeyedIterable; static (obj?: { [key: K]: V }): KeyedIterable; @@iterator(): Iterator<[K,V]>; toSeq(): KeyedSeq; flip(): /*this*/KeyedIterable; mapKeys( mapper: (key: K, value: V, iter: this) => K_, context?: any ): /*this*/KeyedIterable; mapEntries( mapper: (entry: [K,V], index: number, iter: this) => [K_,V_], context?: any ): /*this*/KeyedIterable; concat(...iters: ESIterable<[K,V]>[]): this; map( mapper: (value: V, key: K, iter: this) => V_, context?: any ): /*this*/KeyedIterable; flatMap( mapper: (value: V, key: K, iter: this) => ESIterable<[K_,V_]>, context?: any ): /*this*/KeyedIterable; flatten(depth?: number): /*this*/KeyedIterable; flatten(shallow?: boolean): /*this*/KeyedIterable; } declare class IndexedIterable extends Iterable { static (iter?: ESIterable): IndexedIterable; @@iterator(): Iterator; toSeq(): IndexedSeq; fromEntrySeq(): KeyedSeq; interpose(separator: T): this; interleave(...iterables: ESIterable[]): this; splice( index: number, removeNum: number, ...values: T[] ): this; zip( a: ESIterable, $?: null ): IndexedIterable<[T,A]>; zip( a: ESIterable, b: ESIterable, $?: null ): IndexedIterable<[T,A,B]>; zip( a: ESIterable, b: ESIterable, c: ESIterable, $?: null ): IndexedIterable<[T,A,B,C]>; zip( a: ESIterable, b: ESIterable, c: ESIterable, d: ESIterable, $?: null ): IndexedIterable<[T,A,B,C,D]>; zip( a: ESIterable, b: ESIterable, c: ESIterable, d: ESIterable, e: ESIterable, $?: null ): IndexedIterable<[T,A,B,C,D,E]>; zipWith( zipper: (value: T, a: A) => R, a: ESIterable, $?: null ): IndexedIterable; zipWith( zipper: (value: T, a: A, b: B) => R, a: ESIterable, b: ESIterable, $?: null ): IndexedIterable; zipWith( zipper: (value: T, a: A, b: B, c: C) => R, a: ESIterable, b: ESIterable, c: ESIterable, $?: null ): IndexedIterable; zipWith( zipper: (value: T, a: A, b: B, c: C, d: D) => R, a: ESIterable, b: ESIterable, c: ESIterable, d: ESIterable, $?: null ): IndexedIterable; zipWith( zipper: (value: T, a: A, b: B, c: C, d: D, e: E) => R, a: ESIterable, b: ESIterable, c: ESIterable, d: ESIterable, e: ESIterable, $?: null ): IndexedIterable; indexOf(searchValue: T): number; lastIndexOf(searchValue: T): number; findIndex( predicate: (value: T, index: number, iter: this) => mixed, context?: any ): number; findLastIndex( predicate: (value: T, index: number, iter: this) => mixed, context?: any ): number; concat(...iters: ESIterable[]): this; map( mapper: (value: T, index: number, iter: this) => U, context?: any ): /*this*/IndexedIterable; flatMap( mapper: (value: T, index: number, iter: this) => ESIterable, context?: any ): /*this*/IndexedIterable; flatten(depth?: number): /*this*/IndexedIterable; flatten(shallow?: boolean): /*this*/IndexedIterable; } declare class SetIterable extends Iterable { static (iter?: ESIterable): SetIterable; @@iterator(): Iterator; toSeq(): SetSeq; concat(...iters: ESIterable[]): this; // `map` and `flatMap` cannot be defined further up the hiearchy, because the // implementation for `KeyedIterable` allows the value type to change without // constraining the key type. That does not work for `SetIterable` - the value // and key types *must* match. map( mapper: (value: T, value: T, iter: this) => U, context?: any ): /*this*/SetIterable; flatMap( mapper: (value: T, value: T, iter: this) => ESIterable, context?: any ): /*this*/SetIterable; flatten(depth?: number): /*this*/SetIterable; flatten(shallow?: boolean): /*this*/SetIterable; } declare class Collection extends _Iterable { size: number; } declare class KeyedCollection extends Collection mixins KeyedIterable { toSeq(): KeyedSeq; } declare class IndexedCollection extends Collection mixins IndexedIterable { toSeq(): IndexedSeq; } declare class SetCollection extends Collection mixins SetIterable { toSeq(): SetSeq; } declare class Seq extends _Iterable { static (iter: KeyedSeq): KeyedSeq; static (iter: SetSeq): SetSeq; static (iter?: ESIterable): IndexedSeq; static (iter: { [key: K]: V }): KeyedSeq; static isSeq(maybeSeq: any): boolean; static of(...values: T[]): IndexedSeq; size: ?number; cacheResult(): this; toSeq(): this; } declare class KeyedSeq extends Seq mixins KeyedIterable { static (iter?: ESIterable<[K,V]>): KeyedSeq; static (iter?: { [key: K]: V }): KeyedSeq; } declare class IndexedSeq extends Seq mixins IndexedIterable { static (iter?: ESIterable): IndexedSeq; static of(...values: T[]): IndexedSeq; } declare class SetSeq extends Seq mixins SetIterable { static (iter?: ESIterable): IndexedSeq; static of(...values: T[]): SetSeq; } declare class List extends IndexedCollection { static (iterable?: ESIterable): List; static isList(maybeList: any): boolean; static of(...values: T[]): List; set(index: number, value: U): List; delete(index: number): this; remove(index: number): this; insert(index: number, value: U): List; clear(): this; push(...values: U[]): List; pop(): this; unshift(...values: U[]): List; shift(): this; update(updater: (value: this) => List): List; update(index: number, updater: (value: T) => U): List; update(index: number, notSetValue: U, updater: (value: T) => U): List; merge(...iterables: ESIterable[]): List; mergeWith( merger: (previous: T, next: U, key: number) => V, ...iterables: ESIterable[] ): List; mergeDeep(...iterables: ESIterable[]): List; mergeDeepWith( merger: (previous: T, next: U, key: number) => V, ...iterables: ESIterable[] ): List; setSize(size: number): List; setIn(keyPath: ESIterable, value: any): List; deleteIn(keyPath: ESIterable, value: any): this; removeIn(keyPath: ESIterable, value: any): this; updateIn(keyPath: ESIterable, notSetValue: any, value: any): List; updateIn(keyPath: ESIterable, value: any): List; mergeIn(keyPath: ESIterable, ...iterables: ESIterable[]): List; mergeDeepIn(keyPath: ESIterable, ...iterables: ESIterable[]): List; withMutations(mutator: (mutable: this) => any): this; asMutable(): this; asImmutable(): this; // Overrides that specialize return types map( mapper: (value: T, index: number, iter: this) => M, context?: any ): List; flatMap( mapper: (value: T, index: number, iter: this) => ESIterable, context?: any ): List; flatten(depth?: number): /*this*/List; flatten(shallow?: boolean): /*this*/List; } declare class Map extends KeyedCollection { static (): Map; static (obj?: {[key: string]: V}): Map; static (iterable?: ESIterable<[K,V]>): Map; static isMap(maybeMap: any): boolean; set(key: K_, value: V_): Map; delete(key: K): this; remove(key: K): this; clear(): this; update(updater: (value: this) => Map): Map; update(key: K, updater: (value: V) => V_): Map; update(key: K, notSetValue: V_, updater: (value: V) => V_): Map; merge( ...iterables: (ESIterable<[K_,V_]> | { [key: K_]: V_ })[] ): Map; mergeWith( merger: (previous: V, next: W, key: number) => X, ...iterables: ESIterable[] ): Map; mergeDeep( ...iterables: (ESIterable<[K_,V_]> | { [key: K_]: V_ })[] ): Map; mergeDeepWith( merger: (previous: V, next: W, key: number) => X, ...iterables: ESIterable[] ): Map; setIn(keyPath: ESIterable, value: any): Map; deleteIn(keyPath: ESIterable, value: any): this; removeIn(keyPath: ESIterable, value: any): this; updateIn(keyPath: ESIterable, notSetValue: any, value: any): Map; updateIn(keyPath: ESIterable, value: any): Map; mergeIn(keyPath: ESIterable, ...iterables: ESIterable[]): Map; mergeDeepIn(keyPath: ESIterable, ...iterables: ESIterable[]): Map; withMutations(mutator: (mutable: this) => any): this; asMutable(): this; asImmutable(): this; // Overrides that specialize return types map( mapper: (value: V, key: K, iter: this) => V_, context?: any ): Map; flatMap( mapper: (value: V, key: K, iter: this) => ESIterable<[K_,V_]>, context?: any ): Map; flip(): Map; mapKeys( mapper: (key: K, value: V, iter: this) => K_, context?: any ): Map; flatten(depth?: number): /*this*/Map; flatten(shallow?: boolean): /*this*/Map; } // OrderedMaps have nothing that Maps do not have. We do not need to override constructor & other statics declare class OrderedMap extends Map { static isOrderedMap(maybeOrderedMap: any): bool; } declare class Set extends SetCollection { static (iterable?: ESIterable): Set; static isSet(maybeSet: any): boolean; static of(...values: T[]): Set; static fromKeys(iter: ESIterable<[T,any]>): Set; static fromKeys(iter: { [key: string]: any }): Set; add(value: U): Set; delete(value: T): this; remove(value: T): this; clear(): this; union(...iterables: ESIterable[]): Set; merge(...iterables: ESIterable[]): Set; intersect(...iterables: ESIterable[]): Set; subtract(...iterables: ESIterable[]): Set; withMutations(mutator: (mutable: this) => any): this; asMutable(): this; asImmutable(): this; // Overrides that specialize return types map( mapper: (value: T, value: T, iter: this) => M, context?: any ): Set; flatMap( mapper: (value: T, value: T, iter: this) => ESIterable, context?: any ): Set; flatten(depth?: number): /*this*/Set; flatten(shallow?: boolean): /*this*/Set; } // OrderedSets have nothing that Sets do not have. We do not need to override constructor & other statics declare class OrderedSet extends Set { static isOrderedSet(maybeOrderedSet: any): bool; } declare class Stack extends IndexedCollection { static (iterable?: ESIterable): Stack; static isStack(maybeStack: any): boolean; static of(...values: T[]): Stack; peek(): T; clear(): this; unshift(...values: U[]): Stack; unshiftAll(iter: ESIterable): Stack; shift(): this; push(...values: U[]): Stack; pushAll(iter: ESIterable): Stack; pop(): this; withMutations(mutator: (mutable: this) => any): this; asMutable(): this; asImmutable(): this; // Overrides that specialize return types map( mapper: (value: T, index: number, iter: this) => U, context?: any ): Stack; flatMap( mapper: (value: T, index: number, iter: this) => ESIterable, context?: any ): Stack; flatten(depth?: number): /*this*/Stack; flatten(shallow?: boolean): /*this*/Stack; } declare function Range(start?: number, end?: number, step?: number): IndexedSeq; declare function Repeat(value: T, times?: number): IndexedSeq; //TODO: Once flow can extend normal Objects we can change this back to actually reflect Record behavior. // For now fallback to any to not break existing Code declare class Record { static (spec: T, name?: string): /*T & Record*/any; get(key: $Keys): A; set(key: $Keys, value: A): /*T & Record*/this; remove(key: $Keys): /*T & Record*/this; } declare function fromJS(json: any, reviver?: (k: any, v: Iterable) => any): any; declare function is(first: any, second: any): boolean; export { Iterable, Collection, Seq, // These classes do not actually exist under these names. But it is useful to // have the types available. KeyedIterable, IndexedIterable, SetIterable, KeyedCollection, IndexedCollection, SetCollection, KeyedSeq, IndexedSeq, SetSeq, List, Map, OrderedMap, OrderedSet, Range, Repeat, Record, Set, Stack, fromJS, is, }