Repository navigation
for-of does not work with some DOM collections when target is ES6 #2695
Description
Activity
- addedBugA bug in TypeScriptA bug in TypeScriptES6Relates to the ES6 SpecRelates to the ES6 Spec
on Apr 9, 2015 Zhengbo Li (@zhengbli) would this be covered in your change?
(This would also require making two versions of dom.d.ts - for ES5 and ES6.)
yup. that is correct.
This should also be supported in ES3/ES5 since the emitted loop is just looping over the indexes.
iterators relay on symbols and these are defined in ES6. I think what we need is to allow iterating
ArrayLikein ES3/ES5 (#2862).Dustin Griffith (@djarekg) That is not correct. It can also require converting NodeList to an array first (with slice) to handle the livelist getting modified during iteration. See #2696
Please do not forget to include in this list
TouchListinterface. Thanks.Kagami Sascha Rosylight (@saschanaz) has added support for:
- NodeList
- NodeListOf
- DOMTokenList
The other interfaces do not seem to be iterable in the spec. Arnav Singh (@Arnavion) any ideas?
They're not
iterable<>but they are ArrayClass, eg CSSRuleList. That means their prototype is supposed to be an Array instead of Object and so they have all the properties of Array including [Symbol.iterator], although no browser has actually gone that far, not even Nightly.NodeList is also supposed to be ArrayClass instead of
iterable<>, but Chrome had problems with it and (temporarily?) abandoned it. FF has an open bug to convert NodeList from iterable to ArrayClass but so far nothing has happened. I don't know what browsers' plan for these "ArrayClass" interfaces - I would guess it's likely that all ArrayClass interfaces will eventually be iterable even if they aren't full-blown Arrays.The array iterator
Array.prototype[Symbol.iterator]is also usable for all DOM collections, and this is what Nightly does. For example,CSSRuleList.prototype[Symbol.iterator] === Array.prototype[Symbol.iterator]is true in Nightly. This is intentional - ArrayIterator is supposed to work with ArrayLikes. So even in browsers where DOM collection prototypes don't already have a Symbol.iterator property, assigning it with, sayCSSRuleList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];, works and makes them iterable with for-of. This would be an argument for TS to allow for-of for these types. The user just needs to add a polyfill to assign the [Symbol.iterator] property on all the DOM list prototypes they're interested in iterating with for-of. But these will have to be custom polyfills - I don't know any polyfill library that adds Symbol.iterator properties to all DOM collections. Babel (core-js) does it but only for NodeList.On the other hand, Array.from() works for them since they are array-likes, and even in TS they implicitly extend ArrayLike<T> so Array.from()'s signature is not a problem. So that's an argument against allowing for-of for these types in TS.
So basically, from the user's point of view, either they use a polyfill for Array.from, and use Array.from to convert all their DOM collections before using for-of. This requires no change from TS, and such a polyfill already exists. (Then there was no point to adding [Symbol.iterator] to NodeList either, but anyway...)
Or, TS allows for-of with all DOM collections, and the user uses a polyfill that adds [Symbol.iterator] properties to all those collections. This does require change from TS, and such a polyfill doesn't already exist.
I don't have an opinion either way.
48 remaining items
saschanaz commented
on Apr 24, 2018 ContributorMore actionsKeith Henry (@KeithHenry) That file should replace lib.dom.iterable.d.ts but the upstream does not yet support methods including
entries(). Coming Soon™️, though!What do you mean by upstream does not support, do you mean iterators, in general, are broken? or is this purely a type definition issue?
saschanaz commented
on May 7, 2018 ContributorMore actionsAh, by upstream I mean this one.
saschanaz commented
on Nov 9, 2018 ContributorMore actionsThis can be closed now as lib.dom.iterable.d.ts have iterators for MediaList, StyleSheetList, CSSRuleList, and many more.
Reacted by Veniamin Krol and Claudia MeadowsReacted by Veniamin Krol, S. B. Tam, Zéfling and Benoit SchweblinThis problem still exists for me when trying to iterate over
NodeListOf<Element>. A NodeList is always iterable. Period.Some code:
const triggers = element.querySelectorAll('.trigger'); for (const trigger of triggers) { console.log(trigger); }
The error is on
triggersin VS Code, using typescript 3.2.2.The error:
[ts] Type 'NodeListOf<Element>' is not an array type or a string type. [2495]Technically correct. A NodeList is indeed neither an array nor a string. But
for..ofworks on a great many more kinds of objects, including NodeList.The above code compiles and works fine. So why complain about something that plainly isn't the case?
Reacted by Jacob Pagesaschanaz commented
on Feb 5, 2019 ContributorMore actionsMartijn Saly (@thany) Ensure the target is ES6 or higher. Currently TS does not support for-of on general iterable objects when the target is ES5/ES3.
RyanCavanaugh commented
on Feb 5, 2019 MemberMore actionsOr enable
--downlevelIterationFirst of all, why does TS need to support it at all? It just needs to output the transpiled JS and let JS handle whether the object can be looped over or not.
Apart from that, NodeList is always iterable, in every browser. Some require a indexed for-loop, newer browser suport for..of. But either way the object can be looped over perfectly fine.
If the target is ES5, produce a classic for-loop.
If the target is ES6 or higher, produce a for..of loop.I don't see how this is complicated in any way.
saschanaz commented
on Feb 11, 2019 ContributorMore actionsMartijn Saly (@thany) Have you tried --downlevelIteration (introduced in TS2.3, I forgot about it 😅)? I think that should work.
I've enabled
downlevelIteration(in our tsconfig.json) which doesn't produce any difference. The code still builds and works fine, but I still get the error in VS Code.Also since the update, VS Code has switched to TS 3.3.1, in case you didn't know.
saschanaz commented
on Feb 12, 2019 ContributorMore actionsYou may file a new issue with a repro then.…________________________________ From: Martijn Saly <notifications@github.com> Sent: Tuesday, February 12, 2019 6:59:45 PM To: Microsoft/TypeScript Cc: Kagami Sascha Rosylight; Mention Subject: Re: [Microsoft/TypeScript] for-of does not work with some DOM collections when target is ES6 (#2695) I've enabled downlevelIteration which doesn't produce any difference. The code still builds and works fine, but I still get the error in VS Code. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub<https://nam03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2FTypeScript%2Fissues%2F2695%23issuecomment-462694287&data=02%7C01%7C%7C91a4119c8b1a4177826908d690d0d115%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636855623858410198&sdata=PxkoLBSyS9NJU%2BduETuD0QoOhuRFm8VWZhHgwz52hIo%3D&reserved=0>, or mute the thread<https://nam03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FADPUTsr8pogzyuxsxABnatMGWO9V1y-yks5vMpCRgaJpZM4D9m6v&data=02%7C01%7C%7C91a4119c8b1a4177826908d690d0d115%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636855623858420212&sdata=CXMOuYo2tVV738FKLbb1mWyg5X1Zen1tlLh1BZ1ekU0%3D&reserved=0>.- locked as resolved and limited conversation to collaborators
on Oct 21, 2025
Update: This issue is now only for the following collections:
Originally it was about NodeList as well, but that was fixed (along with DOMTokenList) in #3393
Original:
Seems it just needs an update to lib.es6.d.ts to add the
[Symbol.iterator()]to all the collections that have an indexer and length property.The ones I found that have it in Nightly are below. The rest were either IE-only or didn't exist.Removed my list since it seems FF has more than the specs allow. See zloirock/core-js#137 (comment) for a more accurate list.