Skip to content

Commit

Permalink
Remove the map duplication through higher-order types inspired by mic…
Browse files Browse the repository at this point in the history
  • Loading branch information
errendir committed Aug 25, 2018
1 parent e65e5af commit e071b26
Showing 1 changed file with 58 additions and 108 deletions.
166 changes: 58 additions & 108 deletions type-definitions/Immutable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,56 @@

declare module Immutable {

const CollectionID: unique symbol
type CollectionID = typeof CollectionID
const CollectionKeyedID: unique symbol
type CollectionKeyedID = typeof CollectionKeyedID
const CollectionIndexedID: unique symbol
type CollectionIndexedID = typeof CollectionIndexedID
const CollectionSetID: unique symbol
type CollectionSetID = typeof CollectionSetID

const ListID: unique symbol
type ListID = typeof ListID
const MapID: unique symbol
type MapID = typeof MapID
const OrderedMapID: unique symbol
type OrderedMapID = typeof OrderedMapID
const SetID: unique symbol
type SetID = typeof SetID
const OrderedSetID: unique symbol
type OrderedSetID = typeof OrderedSetID
const StackID: unique symbol
type StackID = typeof StackID

const SeqID: unique symbol
type SeqID = typeof SeqID
const SeqKeyedID: unique symbol
type SeqKeyedID = typeof SeqKeyedID
const SeqIndexedID: unique symbol
type SeqIndexedID = typeof SeqIndexedID
const SeqSetID: unique symbol
type SeqSetID = typeof SeqSetID

interface Collections<K, V> {
[CollectionID]: Collection<K,V>
[CollectionKeyedID]: Collection.Keyed<K,V>
[CollectionIndexedID]: Collection.Indexed<V>
[CollectionSetID]: Collection.Set<V>

[ListID]: List<V>
[MapID]: Map<K,V>
[OrderedMapID]: OrderedMap<K,V>
[SetID]: Set<V>
[OrderedSetID]: OrderedSet<V>
[StackID]: Stack<V>

[SeqID]: Seq<K,V>
[SeqKeyedID]: Seq.Keyed<K,V>
[SeqIndexedID]: Seq.Indexed<V>
[SeqSetID]: Seq.Set<V>
}

/**
* Lists are ordered indexed dense collections, much like a JavaScript
* Array.
Expand Down Expand Up @@ -758,7 +808,7 @@ declare module Immutable {
export function Map<K, V>(): Map<K, V>;
export function Map(): Map<any, any>;

export interface Map<K, V> extends Collection.Keyed<K, V> {
export interface Map<K, V, ConcreteCollectionID extends keyof Collections<any,any> = MapID> extends Collection.Keyed<K, V, ConcreteCollectionID> {

/**
* The number of entries in this Map.
Expand Down Expand Up @@ -1316,18 +1366,6 @@ declare module Immutable {

// Sequence algorithms

/**
* Returns a new Map with values passed through a
* `mapper` function.
*
* Map({ a: 1, b: 2 }).map(x => 10 * x)
* // Map { a: 10, b: 20 }
*/
map<M>(
mapper: (value: V, key: K, iter: this) => M,
context?: any
): Map<K, M>;

/**
* @see Collection.Keyed.mapKeys
*/
Expand Down Expand Up @@ -1416,7 +1454,7 @@ declare module Immutable {
export function OrderedMap<K, V>(): OrderedMap<K, V>;
export function OrderedMap(): OrderedMap<any, any>;

export interface OrderedMap<K, V> extends Map<K, V> {
export interface OrderedMap<K, V> extends Map<K, V, OrderedMapID> {

/**
* The number of entries in this OrderedMap.
Expand Down Expand Up @@ -1472,21 +1510,6 @@ declare module Immutable {

// Sequence algorithms

/**
* Returns a new OrderedMap with values passed through a
* `mapper` function.
*
* OrderedMap({ a: 1, b: 2 }).map(x => 10 * x)
* // OrderedMap { "a": 10, "b": 20 }
*
* Note: `map()` always returns a new instance, even if it produced the same
* value at every step.
*/
map<M>(
mapper: (value: V, key: K, iter: this) => M,
context?: any
): OrderedMap<K, M>;

/**
* @see Collection.Keyed.mapKeys
*/
Expand Down Expand Up @@ -2440,7 +2463,7 @@ declare module Immutable {

// Reading values

has(key: string): key is keyof TProps;
has(key: string): key is ((keyof TProps) & string);

/**
* Returns the value associated with the provided key, which may be the
Expand Down Expand Up @@ -2656,7 +2679,7 @@ declare module Immutable {
export function Keyed<K, V>(): Seq.Keyed<K, V>;
export function Keyed(): Seq.Keyed<any, any>;

export interface Keyed<K, V> extends Seq<K, V>, Collection.Keyed<K, V> {
export interface Keyed<K, V> extends Seq<K, V, SeqKeyedID>, Collection.Keyed<K, V, SeqKeyedID> {
/**
* Deeply converts this Keyed Seq to equivalent native JavaScript Object.
*
Expand Down Expand Up @@ -2690,24 +2713,6 @@ declare module Immutable {
concat<KC, VC>(...collections: Array<Iterable<[KC, VC]>>): Seq.Keyed<K | KC, V | VC>;
concat<C>(...collections: Array<{[key: string]: C}>): Seq.Keyed<K | string, V | C>;

/**
* Returns a new Seq.Keyed with values passed through a
* `mapper` function.
*
* ```js
* const { Seq } = require('immutable')
* Seq.Keyed({ a: 1, b: 2 }).map(x => 10 * x)
* // Seq { "a": 10, "b": 20 }
* ```
*
* Note: `map()` always returns a new instance, even if it produced the
* same value at every step.
*/
map<M>(
mapper: (value: V, key: K, iter: this) => M,
context?: any
): Seq.Keyed<K, M>;

/**
* @see Collection.Keyed.mapKeys
*/
Expand Down Expand Up @@ -3021,7 +3026,7 @@ declare module Immutable {
export function Seq<V>(obj: {[key: string]: V}): Seq.Keyed<string, V>;
export function Seq(): Seq<any, any>;

export interface Seq<K, V> extends Collection<K, V> {
export interface Seq<K, V, ConcreteCollectionID extends keyof Collections<any,any> = SeqID> extends Collection<K, V, ConcreteCollectionID> {

/**
* Some Seqs can describe their size lazily. When this is the case,
Expand Down Expand Up @@ -3062,43 +3067,6 @@ declare module Immutable {

// Sequence algorithms

/**
* Returns a new Seq with values passed through a
* `mapper` function.
*
* ```js
* const { Seq } = require('immutable')
* Seq([ 1, 2 ]).map(x => 10 * x)
* // Seq [ 10, 20 ]
* ```
*
* Note: `map()` always returns a new instance, even if it produced the same
* value at every step.
*/
map<M>(
mapper: (value: V, key: K, iter: this) => M,
context?: any
): Seq<K, M>;

/**
* Returns a new Seq with values passed through a
* `mapper` function.
*
* ```js
* const { Seq } = require('immutable')
* Seq([ 1, 2 ]).map(x => 10 * x)
* // Seq [ 10, 20 ]
* ```
*
* Note: `map()` always returns a new instance, even if it produced the same
* value at every step.
* Note: used only for sets.
*/
map<M>(
mapper: (value: V, key: K, iter: this) => M,
context?: any
): Seq<M, M>;

/**
* Flat-maps the Seq, returning a Seq of the same type.
*
Expand Down Expand Up @@ -3192,7 +3160,7 @@ declare module Immutable {
export function Keyed<K, V>(collection: Iterable<[K, V]>): Collection.Keyed<K, V>;
export function Keyed<V>(obj: {[key: string]: V}): Collection.Keyed<string, V>;

export interface Keyed<K, V> extends Collection<K, V> {
export interface Keyed<K, V, ConcreteCollectionID extends keyof Collections<any,any> = CollectionKeyedID> extends Collection<K, V, ConcreteCollectionID> {
/**
* Deeply converts this Keyed collection to equivalent native JavaScript Object.
*
Expand Down Expand Up @@ -3240,24 +3208,6 @@ declare module Immutable {
concat<KC, VC>(...collections: Array<Iterable<[KC, VC]>>): Collection.Keyed<K | KC, V | VC>;
concat<C>(...collections: Array<{[key: string]: C}>): Collection.Keyed<K | string, V | C>;

/**
* Returns a new Collection.Keyed with values passed through a
* `mapper` function.
*
* ```js
* const { Collection } = require('immutable')
* Collection.Keyed({ a: 1, b: 2 }).map(x => 10 * x)
* // Seq { "a": 10, "b": 20 }
* ```
*
* Note: `map()` always returns a new instance, even if it produced the
* same value at every step.
*/
map<M>(
mapper: (value: V, key: K, iter: this) => M,
context?: any
): Collection.Keyed<K, M>;

/**
* Returns a new Collection.Keyed of the same type with keys passed through
* a `mapper` function.
Expand Down Expand Up @@ -3735,7 +3685,7 @@ declare module Immutable {
export function Collection<T>(collection: Iterable<T>): Collection.Indexed<T>;
export function Collection<V>(obj: {[key: string]: V}): Collection.Keyed<string, V>;

export interface Collection<K, V> extends ValueObject {
export interface Collection<K, V, ConcreteCollectionID extends keyof Collections<any,any> = CollectionID> extends ValueObject {

// Value equality

Expand Down Expand Up @@ -4079,7 +4029,7 @@ declare module Immutable {
map<M>(
mapper: (value: V, key: K, iter: this) => M,
context?: any
): Collection<K, M>;
): Collections<K, M>[ConcreteCollectionID];

/**
* Note: used only for sets, which return Collection<M, M> but are otherwise
Expand Down

0 comments on commit e071b26

Please sign in to comment.