microsoft/TypeScript · error · TypeError
Object is not iterable.
Error message
Object is not iterable.
What it means
`__values` downlevels for-of/spread. If the value has neither Symbol.iterator nor a numeric `.length`, and `Symbol.iterator` *does* exist on the runtime, it throws "Object is not iterable." — i.e. the runtime supports iteration but the value isn't iterable.
Source
Thrown at src/compiler/factory/emitHelpers.ts:1047
};
// ES2015 Destructuring Helpers
const valuesHelper: UnscopedEmitHelper = {
name: "typescript:values",
importName: "__values",
scoped: false,
text: `
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};`,
};
// ES2015 Generator Helpers
// The __generator helper is used by down-level transformations to emulate the runtime
// semantics of an ES2015 generator function. When called, this helper returns an
// object that implements the Iterator protocol, in that it has `next`, `return`, and
// `throw` methods that step through the generator when invoked.
//
// parameters:
// @param thisArg The value to use as the `this` binding for the transformed generator body.
// @param body A function that acts as the transformed generator body.
//
// variables:
// _ Persistent state for the generator that is shared between the helper and the
// generator body. The state object has the following members:
// sent() - A method that returns or throws the current completion value.
View on GitHub (pinned to b465fdbfe1)
Solutions
- Ensure the value is iterable (Array, Map, Set, generator, etc.) before iterating.
- Add a null/iterable guard around the loop.
- For plain objects use Object.entries/keys/values instead of for-of on the object.
Example fix
// before
const obj = { a: 1 };
for (const x of obj) { } // throws "Object is not iterable."
// after
for (const x of Object.entries(obj)) { }
// or guard:
if (obj && obj[Symbol.iterator]) for (const x of obj) { } Defensive patterns
Strategy: type-guard
Validate before calling
function assertIterable(v: unknown): void {
if (v == null || (typeof (v as any)[Symbol.iterator] !== "function" && typeof (v as any).length !== "number")) {
throw new TypeError("Object is not iterable.");
}
} Type guard
function isIterable<T>(v: unknown): v is Iterable<T> {
return v != null && typeof (v as any)[Symbol.iterator] === "function";
} Prevention
- Guard for-of loops when the source can be null/undefined.
- Use Object.entries/keys/values for plain objects instead of for-of.
- Type the source as Iterable<T> so the compiler catches misuse.
When it happens
Trigger: for-of (or spread/destructuring) over null, undefined, a plain object without an iterator, or any non-iterable non-array-like value.
Common situations: Iterating an object literal expecting entries; a function returning null where an iterable was expected; spreading a Map without calling .values()/.entries().
Related errors
- Symbol.iterator is not defined.
- Function expected
- Cannot add initializers after decoration has completed
- Object expected
- Symbol.asyncIterator is not defined.
AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12).
Data as JSON: /api/errors/496aba346bb5e282.
Report an issue: GitHub.