Typescript: Iterating ES6 Map object

Created on 2 Feb 2016  路  14Comments  路  Source: microsoft/TypeScript

When I try to iterate over a Map object as described in MDN: Map, i.e.

let map = new Map<string, string>();

map.set("key", "value");

for (let value of map.values()) {
    console.debug(value);
}

the compiler complains:

Type 'IterableIterator<string>' is not an array type or a string type.

Is this a bug, or am I doing something wrong?

External

Most helpful comment

This seems pretty strange. Why should it be necessary to transpile to ES6 and then again with Babel (the process of which incidentally messes up source maps in our project) just in order to have a standard ES6 feature work? Isn't TypeScript supposed to be a superset of ES6 and the TypeScript compiler a drop-in replacement for Babel?

All 14 comments

Works fine in master (not sure about the most recent release version). Also, there is no put in Map. Are you sure you're using the right .d.ts file?

I meant Map.set, sorry. I'm using v1.7.3, I'll try v1.7.5 and then v1.8.0-beta!

The error message sounds like you're targeting ES5 and forcing it to use lib.es6.d.ts to be able to get Map (or perhaps from some other .d.ts). TS doesn't support iterating IterableIterator with ES5 target, only strings and arrays.

looks like a duplicate of #4947, or at least stemming from the same issue.

@mhegazy #4947 is to allow for-of on array-likes in ES5. Map.values() returns an iterator and is only available in ES6 anyway.

@Arnavion is right, targeting ES6 solves the problem. I'm now transpiling TS to ES6 and then ES6 to ES5 with Babel. Thank you!

This seems pretty strange. Why should it be necessary to transpile to ES6 and then again with Babel (the process of which incidentally messes up source maps in our project) just in order to have a standard ES6 feature work? Isn't TypeScript supposed to be a superset of ES6 and the TypeScript compiler a drop-in replacement for Babel?

TypeScript is a syntactic superset of JavaScript, not a functional superset. When syntax and functionality intersect, there is a bit of a grey area. When targeting ES5, TypeScript assumes that only number indexed based objects (ArrayLike) can be down-emitted with for ... of because those are only the functional structures which are guaranteed to be supported by ES5.

11209 discusses this in more detail with other possible solutions when you cross the syntactic/functional barrier of ES6.

Indeed, even though TS emits ES5-compliant JS, that JS is not ES6-conformant. For example, the JS emitted for for-of even for arrays does not account for iterators because it assumes they don't exist. Babel works around this by requiring core-js to provide the ES6 functionality. TS should definitely not be considered a drop-in replacement for Babel.

I'd be totally fine if core-js were a requirement. In fact we are using core-js already for exactly this reason. The problem is that it doesn't help much to have those (type-safe!) ES6 collections classes available, if it's not even possible to iterate over them.

@Arnavion I've also described our trials and tribulations in greater detail in the linked issue (#11209). It's newer and has more active participants, so let's use that for future discussion. ;)

I got the error when using map, even when compiling to target: "ES6" in VSC

  mergeAll() {
    this.streams.values().map(stream => stream.subscribe(this.stream))
  }

Worked when I switched to a for loop instead (which I normally try to avoid to keep more functional)

    for (let stream of this.streams.values()) {
      stream.subscribe(this.stream)
    }

Any suggestions?

Assuming you have a polyfill for newer Array features, one not-awful workaround I've come up with is to use the second mapFn argument to Array.from as a replacement for the lack of for...of support:

const map = new Map<string, number>();
map.set('a', 1);
map.set('b', 2);

Array.from(map.values(), (value: number) => {
  alert(value);
});

--downLevelIteration is a better solution @dylanpyle

This issue predates the availability of that feature.

Was this page helpful?
0 / 5 - 0 ratings