<p dir="auto">When I try to iterate over a <code class="notranslate">Map</code> object as described in <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map#Iterating_Maps_with_for..of" rel="nofollow">MDN: Map</a>, i.e.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let map = new Map&lt;string, string&gt;();

map.set(&quot;key&quot;, &quot;value&quot;);

for (let value of map.values()) {
    console.debug(value);
}"><pre class="notranslate"><span class="pl-k">let</span> <span class="pl-s1">map</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Map</span><span class="pl-c1">&lt;</span><span class="pl-s1">string</span><span class="pl-kos">,</span> <span class="pl-s1">string</span><span class="pl-c1">&gt;</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-s1">map</span><span class="pl-kos">.</span><span class="pl-en">set</span><span class="pl-kos">(</span><span class="pl-s">"key"</span><span class="pl-kos">,</span> <span class="pl-s">"value"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">for</span> <span class="pl-kos">(</span><span class="pl-k">let</span> <span class="pl-s1">value</span> <span class="pl-k">of</span> <span class="pl-s1">map</span><span class="pl-kos">.</span><span class="pl-en">values</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">debug</span><span class="pl-kos">(</span><span class="pl-s1">value</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">the compiler complains:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Type 'IterableIterator&lt;string&gt;' is not an array type or a string type."><pre class="notranslate"><code class="notranslate">Type 'IterableIterator&lt;string&gt;' is not an array type or a string type.
</code></pre></div>
<p dir="auto">Is this a bug, or am I doing something wrong?</p>
<p dir="auto"><code class="notranslate">NodeList</code> interface is defined as iterable in DOM4, but by design it cannot be directly used in for-of loop because we cannot declare it as iterable in ES5.</p>
<h3 dir="auto">Suggestion</h3>
<p dir="auto">Introduce a ES5-compatible way to declare iterable interfaces (Similar to what discussed in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="70098056" data-permission-text="Title is private" data-url="https://github.com/microsoft/TypeScript/issues/2862" data-hovercard-type="issue" data-hovercard-url="/microsoft/TypeScript/issues/2862/hovercard" href="https://github.com/microsoft/TypeScript/issues/2862">#2862</a>)</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// WebIDL-like way
interface NodeList {
  iterable&lt;Node&gt;
}

// extends-like way
interface NodeList iterable&lt;Node&gt; {}"><pre class="notranslate"><span class="pl-c">// WebIDL-like way</span>
<span class="pl-k">interface</span> <span class="pl-smi">NodeList</span> <span class="pl-kos">{</span>
  <span class="pl-c1">iterable</span><span class="pl-c1">&lt;</span><span class="pl-smi">Node</span><span class="pl-c1">&gt;</span>
<span class="pl-kos">}</span>

<span class="pl-c">// extends-like way</span>
<span class="pl-k">interface</span> <span class="pl-smi">NodeList</span> <span class="pl-s1">iterable</span><span class="pl-c1">&lt;</span><span class="pl-smi">Node</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span><span class="pl-kos">}</span></pre></div>
<p dir="auto"><code class="notranslate">iterable&lt;T&gt;</code> in ES6 mode will work as a shorthand of <code class="notranslate">[Symbol.iterator](): IterableIterator&lt;T&gt;</code> but in ES5 mode will just make an internal flag to be allowed in for-of loop.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// NodeList is marked as iterable,
// it has .length property and index signature for ES5 emit, so all good
for (let node of document.querySelectorAll(&quot;...&quot;)) {
}"><pre class="notranslate"><span class="pl-c">// NodeList is marked as iterable,</span>
<span class="pl-c">// it has .length property and index signature for ES5 emit, so all good</span>
<span class="pl-k">for</span> <span class="pl-kos">(</span><span class="pl-k">let</span> <span class="pl-s1">node</span> <span class="pl-k">of</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">querySelectorAll</span><span class="pl-kos">(</span><span class="pl-s">"..."</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This will make it work both on ES5 and ES6 without changing emit.</p>