@@ -25,27 +25,81 @@ namespace ts {
25
25
}
26
26
27
27
/** ES6 Map interface, only read methods included. */
28
- export interface ReadonlyMap < T > {
29
- get ( key : string ) : T | undefined ;
30
- has ( key : string ) : boolean ;
31
- forEach ( action : ( value : T , key : string ) => void ) : void ;
28
+ export interface ReadonlyESMap < K , V > {
29
+ get ( key : K ) : V | undefined ;
30
+ has ( key : K ) : boolean ;
31
+ forEach ( action : ( value : V , key : K ) => void ) : void ;
32
32
readonly size : number ;
33
- keys ( ) : Iterator < string > ;
34
- values ( ) : Iterator < T > ;
35
- entries ( ) : Iterator < [ string , T ] > ;
33
+ keys ( ) : Iterator < K > ;
34
+ values ( ) : Iterator < V > ;
35
+ entries ( ) : Iterator < [ K , V ] > ;
36
36
}
37
37
38
38
/** ES6 Map interface. */
39
- export interface Map < T > extends ReadonlyMap < T > {
40
- set ( key : string , value : T ) : this;
41
- delete ( key : string ) : boolean ;
39
+ export interface ESMap < K , V > extends ReadonlyESMap < K , V > {
40
+ set ( key : K , value : V ) : this;
41
+ delete ( key : K ) : boolean ;
42
42
clear ( ) : void ;
43
43
}
44
44
45
+ /** ES6 Map interface, only read methods included. */
46
+ export interface ReadonlyMap < T > extends ReadonlyESMap < string , T > {
47
+ }
48
+
49
+ /** ES6 Map interface. */
50
+ export interface Map < T > extends ESMap < string , T > , ReadonlyMap < T > {
51
+ }
52
+
45
53
/* @internal */
46
54
export interface MapConstructor {
47
55
// eslint-disable-next-line @typescript-eslint/prefer-function-type
48
- new < T > ( ) : Map < T > ;
56
+ new < K , V > ( ) : ESMap < K , V > ;
57
+ }
58
+
59
+ export interface ReadonlySet < T > {
60
+ readonly size : number ;
61
+ has ( value : T ) : boolean ;
62
+ forEach ( action : ( value : T , key : T ) => void ) : void ;
63
+ keys ( ) : Iterator < T > ;
64
+ values ( ) : Iterator < T > ;
65
+ entries ( ) : Iterator < [ T , T ] > ;
66
+ }
67
+
68
+ export interface Set < T > extends ReadonlySet < T > {
69
+ add ( value : T ) : this;
70
+ delete ( value : T ) : boolean ;
71
+ clear ( ) : void ;
72
+ }
73
+
74
+ /* @internal */
75
+ export interface SetConstructor {
76
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
77
+ new < T > ( ) : Set < T > ;
78
+ }
79
+
80
+ export interface WeakMap < K extends object , V > {
81
+ get ( key : K ) : V | undefined ;
82
+ has ( key : K ) : boolean ;
83
+ set ( key : K , value : V ) : this;
84
+ delete ( key : K ) : boolean ;
85
+ }
86
+
87
+ /* @internal */
88
+ export interface WeakMapConstructor {
89
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
90
+ new < K extends object , V > ( ) : WeakMap < K , V > ;
91
+ }
92
+
93
+ export interface WeakSet < T extends object > {
94
+ has ( key : T ) : boolean ;
95
+ add ( key : T ) : this;
96
+ delete ( key : T ) : boolean ;
97
+ }
98
+
99
+ /* @internal */
100
+ export interface WeakSetConstructor {
101
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
102
+ new < T extends object > ( ) : WeakSet < T > ;
49
103
}
50
104
51
105
/** ES6 Iterator type. */
@@ -75,8 +129,12 @@ namespace ts {
75
129
/* @internal */
76
130
namespace ts {
77
131
// Natives
78
- // NOTE: This must be declared in a separate block from the one below so that we don't collide with the exported definition of `Map`.
79
- declare const Map : ( new < T > ( ) => Map < T > ) | undefined ;
132
+ // NOTE: This must be declared in a separate block from the one below so that we don't collide with the exported definitions of `Map` and `Set`.
133
+
134
+ declare const Map : MapConstructor | undefined ;
135
+ declare const Set : SetConstructor | undefined ;
136
+ declare const WeakMap : WeakMapConstructor | undefined ;
137
+ declare const WeakSet : WeakSetConstructor | undefined ;
80
138
81
139
/**
82
140
* Returns the native Map implementation if it is available and compatible (i.e. supports iteration).
@@ -86,28 +144,79 @@ namespace ts {
86
144
// eslint-disable-next-line no-in-operator
87
145
return typeof Map !== "undefined" && "entries" in Map . prototype ? Map : undefined ;
88
146
}
147
+
148
+ /**
149
+ * Returns the native Set implementation if it is available and compatible (i.e. supports iteration).
150
+ */
151
+ export function tryGetNativeSet ( ) : SetConstructor | undefined {
152
+ // Internet Explorer's Set doesn't support iteration, so don't use it.
153
+ // eslint-disable-next-line no-in-operator
154
+ return typeof Set !== "undefined" && "entries" in Set . prototype ? Set : undefined ;
155
+ }
156
+
157
+ /**
158
+ * Returns the native WeakMap implementation if it is available.
159
+ */
160
+ export function tryGetNativeWeakMap ( ) : WeakMapConstructor | undefined {
161
+ return typeof WeakMap !== "undefined" ? WeakMap : undefined ;
162
+ }
163
+
164
+ /**
165
+ * Returns the native WeakSet implementation if it is available.
166
+ */
167
+ export function tryGetNativeWeakSet ( ) : WeakSetConstructor | undefined {
168
+ return typeof WeakSet !== "undefined" ? WeakSet : undefined ;
169
+ }
89
170
}
90
171
91
172
/* @internal */
92
173
namespace ts {
93
174
export const emptyArray : never [ ] = [ ] as never [ ] ;
94
175
95
176
export const Map : MapConstructor = tryGetNativeMap ( ) || ( ( ) => {
96
- // NOTE: createMapShim will be defined for typescriptServices.js but not for tsc.js, so we must test for it.
177
+ // NOTE: ts. createMapShim will be defined for typescriptServices.js but not for tsc.js, so we must test for it.
97
178
if ( typeof createMapShim === "function" ) {
98
179
return createMapShim ( ) ;
99
180
}
100
181
throw new Error ( "TypeScript requires an environment that provides a compatible native Map implementation." ) ;
101
182
} ) ( ) ;
102
183
184
+ export const Set : SetConstructor = tryGetNativeSet ( ) || ( ( ) => {
185
+ // NOTE: ts.createSetShim will be defined for typescriptServices.js but not for tsc.js, so we must test for it.
186
+ if ( typeof createSetShim === "function" ) {
187
+ return createSetShim ( ) ;
188
+ }
189
+ throw new Error ( "TypeScript requires an environment that provides a compatible native Set implementation." ) ;
190
+ } ) ( ) ;
191
+
192
+ export const WeakMap : WeakMapConstructor = tryGetNativeWeakMap ( ) || ( ( ) => {
193
+ // NOTE: ts.createWeakMapShim will be defined for typescriptServices.js but not for tsc.js, so we must test for it.
194
+ if ( typeof createWeakMapShim === "function" ) {
195
+ return createWeakMapShim ( ) ;
196
+ }
197
+ throw new Error ( "TypeScript requires an environment that provides a compatible native WeakMap implementation." ) ;
198
+ } ) ( ) ;
199
+
200
+ export const WeakSet : WeakSetConstructor = tryGetNativeWeakSet ( ) || ( ( ) => {
201
+ // NOTE: ts.createWeakSetShim will be defined for typescriptServices.js but not for tsc.js, so we must test for it.
202
+ if ( typeof createWeakSetShim === "function" ) {
203
+ return createWeakSetShim ( ) ;
204
+ }
205
+ throw new Error ( "TypeScript requires an environment that provides a compatible native WeakSet implementation." ) ;
206
+ } ) ( ) ;
207
+
103
208
/** Create a new map. */
104
- export function createMap < T > ( ) : Map < T > {
105
- return new Map < T > ( ) ;
209
+ export function createMap < T > ( ) : Map < T > ;
210
+ export function createMap < K , V > ( ) : ESMap < K , V > ;
211
+ export function createMap < K , V > ( ) : ESMap < K , V > {
212
+ return new Map < K , V > ( ) ;
106
213
}
107
214
108
215
/** Create a new map from an array of entries. */
109
- export function createMapFromEntries < T > ( entries : [ string , T ] [ ] ) : Map < T > {
110
- const map = createMap < T > ( ) ;
216
+ export function createMapFromEntries < T > ( entries : readonly [ string , T ] [ ] ) : Map < T > ;
217
+ export function createMapFromEntries < K , V > ( entries : readonly [ K , V ] [ ] ) : ESMap < K , V > ;
218
+ export function createMapFromEntries < K , V > ( entries : readonly [ K , V ] [ ] ) : ESMap < K , V > {
219
+ const map = createMap < K , V > ( ) ;
111
220
for ( const [ key , value ] of entries ) {
112
221
map . set ( key , value ) ;
113
222
}
@@ -116,7 +225,7 @@ namespace ts {
116
225
117
226
/** Create a new map from a template object is provided, the map will copy entries from it. */
118
227
export function createMapFromTemplate < T > ( template : MapLike < T > ) : Map < T > {
119
- const map : Map < T > = new Map < T > ( ) ;
228
+ const map : Map < T > = new Map < string , T > ( ) ;
120
229
121
230
// Copies keys/values from template. Note that for..in will not throw if
122
231
// template is undefined, and instead will just exit the loop.
@@ -129,6 +238,18 @@ namespace ts {
129
238
return map ;
130
239
}
131
240
241
+ export function createSet < T > ( ) : Set < T > {
242
+ return new Set < T > ( ) ;
243
+ }
244
+
245
+ export function createSetFromValues < T > ( values : readonly T [ ] ) : Set < T > {
246
+ const set = createSet < T > ( ) ;
247
+ for ( const value of values ) {
248
+ set . add ( value ) ;
249
+ }
250
+ return set ;
251
+ }
252
+
132
253
export function length ( array : readonly any [ ] | undefined ) : number {
133
254
return array ? array . length : 0 ;
134
255
}
0 commit comments