Skip to content

Commit e071b26

Browse files
committed
Remove the map duplication through higher-order types inspired by microsoft/TypeScript#25947 (comment)
1 parent e65e5af commit e071b26

File tree

1 file changed

+58
-108
lines changed

1 file changed

+58
-108
lines changed

type-definitions/Immutable.d.ts

Lines changed: 58 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,56 @@
9999

100100
declare module Immutable {
101101

102+
const CollectionID: unique symbol
103+
type CollectionID = typeof CollectionID
104+
const CollectionKeyedID: unique symbol
105+
type CollectionKeyedID = typeof CollectionKeyedID
106+
const CollectionIndexedID: unique symbol
107+
type CollectionIndexedID = typeof CollectionIndexedID
108+
const CollectionSetID: unique symbol
109+
type CollectionSetID = typeof CollectionSetID
110+
111+
const ListID: unique symbol
112+
type ListID = typeof ListID
113+
const MapID: unique symbol
114+
type MapID = typeof MapID
115+
const OrderedMapID: unique symbol
116+
type OrderedMapID = typeof OrderedMapID
117+
const SetID: unique symbol
118+
type SetID = typeof SetID
119+
const OrderedSetID: unique symbol
120+
type OrderedSetID = typeof OrderedSetID
121+
const StackID: unique symbol
122+
type StackID = typeof StackID
123+
124+
const SeqID: unique symbol
125+
type SeqID = typeof SeqID
126+
const SeqKeyedID: unique symbol
127+
type SeqKeyedID = typeof SeqKeyedID
128+
const SeqIndexedID: unique symbol
129+
type SeqIndexedID = typeof SeqIndexedID
130+
const SeqSetID: unique symbol
131+
type SeqSetID = typeof SeqSetID
132+
133+
interface Collections<K, V> {
134+
[CollectionID]: Collection<K,V>
135+
[CollectionKeyedID]: Collection.Keyed<K,V>
136+
[CollectionIndexedID]: Collection.Indexed<V>
137+
[CollectionSetID]: Collection.Set<V>
138+
139+
[ListID]: List<V>
140+
[MapID]: Map<K,V>
141+
[OrderedMapID]: OrderedMap<K,V>
142+
[SetID]: Set<V>
143+
[OrderedSetID]: OrderedSet<V>
144+
[StackID]: Stack<V>
145+
146+
[SeqID]: Seq<K,V>
147+
[SeqKeyedID]: Seq.Keyed<K,V>
148+
[SeqIndexedID]: Seq.Indexed<V>
149+
[SeqSetID]: Seq.Set<V>
150+
}
151+
102152
/**
103153
* Lists are ordered indexed dense collections, much like a JavaScript
104154
* Array.
@@ -758,7 +808,7 @@ declare module Immutable {
758808
export function Map<K, V>(): Map<K, V>;
759809
export function Map(): Map<any, any>;
760810

761-
export interface Map<K, V> extends Collection.Keyed<K, V> {
811+
export interface Map<K, V, ConcreteCollectionID extends keyof Collections<any,any> = MapID> extends Collection.Keyed<K, V, ConcreteCollectionID> {
762812

763813
/**
764814
* The number of entries in this Map.
@@ -1316,18 +1366,6 @@ declare module Immutable {
13161366

13171367
// Sequence algorithms
13181368

1319-
/**
1320-
* Returns a new Map with values passed through a
1321-
* `mapper` function.
1322-
*
1323-
* Map({ a: 1, b: 2 }).map(x => 10 * x)
1324-
* // Map { a: 10, b: 20 }
1325-
*/
1326-
map<M>(
1327-
mapper: (value: V, key: K, iter: this) => M,
1328-
context?: any
1329-
): Map<K, M>;
1330-
13311369
/**
13321370
* @see Collection.Keyed.mapKeys
13331371
*/
@@ -1416,7 +1454,7 @@ declare module Immutable {
14161454
export function OrderedMap<K, V>(): OrderedMap<K, V>;
14171455
export function OrderedMap(): OrderedMap<any, any>;
14181456

1419-
export interface OrderedMap<K, V> extends Map<K, V> {
1457+
export interface OrderedMap<K, V> extends Map<K, V, OrderedMapID> {
14201458

14211459
/**
14221460
* The number of entries in this OrderedMap.
@@ -1472,21 +1510,6 @@ declare module Immutable {
14721510

14731511
// Sequence algorithms
14741512

1475-
/**
1476-
* Returns a new OrderedMap with values passed through a
1477-
* `mapper` function.
1478-
*
1479-
* OrderedMap({ a: 1, b: 2 }).map(x => 10 * x)
1480-
* // OrderedMap { "a": 10, "b": 20 }
1481-
*
1482-
* Note: `map()` always returns a new instance, even if it produced the same
1483-
* value at every step.
1484-
*/
1485-
map<M>(
1486-
mapper: (value: V, key: K, iter: this) => M,
1487-
context?: any
1488-
): OrderedMap<K, M>;
1489-
14901513
/**
14911514
* @see Collection.Keyed.mapKeys
14921515
*/
@@ -2440,7 +2463,7 @@ declare module Immutable {
24402463

24412464
// Reading values
24422465

2443-
has(key: string): key is keyof TProps;
2466+
has(key: string): key is ((keyof TProps) & string);
24442467

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

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

2693-
/**
2694-
* Returns a new Seq.Keyed with values passed through a
2695-
* `mapper` function.
2696-
*
2697-
* ```js
2698-
* const { Seq } = require('immutable')
2699-
* Seq.Keyed({ a: 1, b: 2 }).map(x => 10 * x)
2700-
* // Seq { "a": 10, "b": 20 }
2701-
* ```
2702-
*
2703-
* Note: `map()` always returns a new instance, even if it produced the
2704-
* same value at every step.
2705-
*/
2706-
map<M>(
2707-
mapper: (value: V, key: K, iter: this) => M,
2708-
context?: any
2709-
): Seq.Keyed<K, M>;
2710-
27112716
/**
27122717
* @see Collection.Keyed.mapKeys
27132718
*/
@@ -3021,7 +3026,7 @@ declare module Immutable {
30213026
export function Seq<V>(obj: {[key: string]: V}): Seq.Keyed<string, V>;
30223027
export function Seq(): Seq<any, any>;
30233028

3024-
export interface Seq<K, V> extends Collection<K, V> {
3029+
export interface Seq<K, V, ConcreteCollectionID extends keyof Collections<any,any> = SeqID> extends Collection<K, V, ConcreteCollectionID> {
30253030

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

30633068
// Sequence algorithms
30643069

3065-
/**
3066-
* Returns a new Seq with values passed through a
3067-
* `mapper` function.
3068-
*
3069-
* ```js
3070-
* const { Seq } = require('immutable')
3071-
* Seq([ 1, 2 ]).map(x => 10 * x)
3072-
* // Seq [ 10, 20 ]
3073-
* ```
3074-
*
3075-
* Note: `map()` always returns a new instance, even if it produced the same
3076-
* value at every step.
3077-
*/
3078-
map<M>(
3079-
mapper: (value: V, key: K, iter: this) => M,
3080-
context?: any
3081-
): Seq<K, M>;
3082-
3083-
/**
3084-
* Returns a new Seq with values passed through a
3085-
* `mapper` function.
3086-
*
3087-
* ```js
3088-
* const { Seq } = require('immutable')
3089-
* Seq([ 1, 2 ]).map(x => 10 * x)
3090-
* // Seq [ 10, 20 ]
3091-
* ```
3092-
*
3093-
* Note: `map()` always returns a new instance, even if it produced the same
3094-
* value at every step.
3095-
* Note: used only for sets.
3096-
*/
3097-
map<M>(
3098-
mapper: (value: V, key: K, iter: this) => M,
3099-
context?: any
3100-
): Seq<M, M>;
3101-
31023070
/**
31033071
* Flat-maps the Seq, returning a Seq of the same type.
31043072
*
@@ -3192,7 +3160,7 @@ declare module Immutable {
31923160
export function Keyed<K, V>(collection: Iterable<[K, V]>): Collection.Keyed<K, V>;
31933161
export function Keyed<V>(obj: {[key: string]: V}): Collection.Keyed<string, V>;
31943162

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

3243-
/**
3244-
* Returns a new Collection.Keyed with values passed through a
3245-
* `mapper` function.
3246-
*
3247-
* ```js
3248-
* const { Collection } = require('immutable')
3249-
* Collection.Keyed({ a: 1, b: 2 }).map(x => 10 * x)
3250-
* // Seq { "a": 10, "b": 20 }
3251-
* ```
3252-
*
3253-
* Note: `map()` always returns a new instance, even if it produced the
3254-
* same value at every step.
3255-
*/
3256-
map<M>(
3257-
mapper: (value: V, key: K, iter: this) => M,
3258-
context?: any
3259-
): Collection.Keyed<K, M>;
3260-
32613211
/**
32623212
* Returns a new Collection.Keyed of the same type with keys passed through
32633213
* a `mapper` function.
@@ -3735,7 +3685,7 @@ declare module Immutable {
37353685
export function Collection<T>(collection: Iterable<T>): Collection.Indexed<T>;
37363686
export function Collection<V>(obj: {[key: string]: V}): Collection.Keyed<string, V>;
37373687

3738-
export interface Collection<K, V> extends ValueObject {
3688+
export interface Collection<K, V, ConcreteCollectionID extends keyof Collections<any,any> = CollectionID> extends ValueObject {
37393689

37403690
// Value equality
37413691

@@ -4079,7 +4029,7 @@ declare module Immutable {
40794029
map<M>(
40804030
mapper: (value: V, key: K, iter: this) => M,
40814031
context?: any
4082-
): Collection<K, M>;
4032+
): Collections<K, M>[ConcreteCollectionID];
40834033

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

0 commit comments

Comments
 (0)