TypeError: x is not iterable

for...of やスプレッドや分割代入に、回せないものを渡したときに出ます。素のオブジェクト、null、通信の結果。原因を多い順に並べ、それぞれ直したコードを載せています。

実行して検証済み処理系Node 22.22.3対応ES2015難易度●●○○○目安8更新

回せないものを、回そうとしたときに出ます。

javascript
for (const value of { a: 1, b: 2 }) {
console.log(value);
}
TypeError: {(intermediate value)(intermediate value)} is not iterable
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
TypeError TypeError TypeError TypeError

素のオブジェクトはfor...of で回せません

{(intermediate value)} は「その場で書いたオブジェクト」という意味です。変数に入れて渡すと、代わりに変数の名前が出ます。

どこで出るか

for...of だけではありません。同じ仕組みを使う場所すべてで出ます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
a 1 b 2 a b
javascript
const list = null;

for (const value of list) {
console.log(value);
}
TypeError: list is not iterable
書き方
for...of for (const x of value)
スプレッド [...value] / f(...value)
配列の分割代入 const [a] = value
Array.from() / new Set() / new Map() new Set(value)
Promise.all() Promise.all(value)

Symbol.iterator を持っているかどうかだけで決まります。 → 反復可能とイテレータ

原因1: 素のオブジェクトを回そうとした

いちばん多い原因です。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
null object false
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
落ちなかった
欲しいもの 使うもの
鍵だけ Object.keys()
値だけ Object.values()
両方 Object.entries()

Object.keys() / values() / entries()

for...in でも回せますが、受け継いだ鍵まで拾うので勧めません。

原因2: nullundefined が来た

javascript
const response = { items: [1, 2], total: 2 };

console.log([...response]);
TypeError: response is not iterable
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
{"items":[1,2],"total":2} [ 1, 2 ]

文言に出るのは、書いた名前であって中身ではありません。 listnull なのか、素のオブジェクトなのかは、これだけでは分かりません。

まず中身を出してください。

javascript
const fake = { length: 2, 0: 'a', 1: 'b' };

console.log([...fake]);
TypeError: fake is not iterable
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'a', 'b' ]

nullundefined だったなら、 回せない形なのではなく、値がまだ入っていないという意味です。

出どころをたどってください。 通信の失敗、まだ届いていない、鍵の綴り違い。

その場で凌ぐなら、空配列に倒します。

javascript
const point = { x: 1, y: 2 };

const [x, y] = point;
TypeError: point is not iterable
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
1 2

ただし、これは原因を隠す書き方でもあります。 「無いのが正常」なときにだけ使ってください。 → Cannot read properties of undefined

原因3: 配列だと思っていたものが違った

通信の結果は、中に包まれていることがよくあります。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 1, 2 ]

response ではなく response.items が配列です。 まず中身を出して確かめてください。

原因4: length があるだけの形

length を持っていても、回せるとは限りません。 Array.from() なら扱えます。

Array.from() / Array.of() / new Array()

ブラウザの NodeListHTMLCollection は、いまはどちらでも扱えます。古い環境向けの記事で Array.prototype.slice.call() を見かけますが、いま書く必要はありません。

原因5: オブジェクトを分割代入で受けた

角括弧と波括弧を取り違えています。

  • [ ]並びから順番に取り出す(配列)
  • { }名前で取り出す(オブジェクト)

自分で回せるようにする

どうしてもそのオブジェクトを回したいなら、Symbol.iterator を持たせます。

ただし、ふつうは Object.entries() で足ります。 自作するのは、独自の順序や終わりの条件があるときだけにしてください。

探しかたの順序

  1. 文言に出ている名前を探す。それが中身を教えてくれるわけではない
  2. その値を console.log()typeof で出す
    • null / undefined だった → 値の出どころを疑う。回し方の問題ではない
    • 素のオブジェクトだった → Object.entries() を挟む
    • 中に配列が入っていた → そちらを渡す
  3. 分割代入なら、[ ]{ } を見直す

このページの実行結果は Node 22.22.3 のものです。文言は処理系と版によって変わります。自分の環境で出た文言で検索してください。

まとめ

  • 出るのは for...of・スプレッド・配列の分割代入new Set() など
  • 判定はSymbol.iterator を持つかだけ
  • 素のオブジェクトは回せない。 Object.entries() を挟む
  • 文言に出るのは書いた名前で、中身ではない。 まず値を出して見る
  • 値が null / undefined だったなら、出どころの問題
  • length があるだけの形は Array.from() で扱う
  • [ ]{ } の取り違えでも出る

この記事の根拠

  1. GetIterator — ECMAScript® 2026 Language Specificationtc39.es
  2. The for-in, for-of, and for-await-of Statements — ECMAScript® 2026 Language Specificationtc39.es
  3. TypeError: 'x' is not iterable — MDNdeveloper.mozilla.org

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)