Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To run a block of TypeScript more than once, pick the loop by what drives the repetition. Use a counted for loop when you know the number of passes or need an index. Use for...of to visit each value in an array or other iterable. Use while when a condition decides whether another pass happens, and do...while when the body must run at least once. Reserve for...in for object property keys, not array values.

Counted loops with for

A counted loop has the form for (initialization; condition; afterthought). JavaScript, and therefore TypeScript, runs the three parts in a fixed order:

  1. The initialization runs once, before the first pass. let i = 0 creates the counter.
  2. The condition is checked before every pass. When it evaluates to false, the loop stops.
  3. The body runs.
  4. The afterthought, usually i++, runs after the body completes, and control returns to the condition check.

A fixed number of passes

for (let i = 0; i < 3; i++) {
  console.log(`Run ${i + 1}`);
}

This prints “Run 1”, “Run 2”, and “Run 3”. The counter starts at zero, and the condition i < 3 fails when i reaches 3, so the body runs exactly three times. The upper bound is exclusive, which is why the comparison is < rather than <= for a zero-based count.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Counting down or using a custom step

The afterthought can be any expression, so the same structure handles reverse order and larger steps:

for (let n = 10; n > 0; n -= 2) {
  console.log(n);
}

This prints 10, 8, 6, 4, and 2.

Looping over array values with for…of

When you need each element and not its position, for...of removes the index bookkeeping:

const names = ["Ada", "Grace", "Linus"];
for (const name of names) {
  console.log(name);
}

The loop variable receives each value in order. The same syntax works with other iterables such as strings, Map, and Set, although the compilation caveats described below apply to non-array iterables. If you also need the position, switch to a counted for loop instead of tracking an index by hand inside a for...of body.

Rank #2
TypeScript Programming Language - Software Engineer & Coder T-Shirt
  • TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
  • TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
  • Lightweight, Classic fit, Double-needle sleeve and bottom hem

Object keys with for…in

for...in iterates over enumerable property keys, and those keys arrive as strings:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const scores = { ada: 91, grace: 88 };
for (const key in scores) {
  console.log(key);
}

This prints “ada” and “grace”. Because it walks keys rather than values, it is the wrong tool for a plain array of values. On arrays, for...in yields index strings such as “0” and “1”, and it can also include custom enumerable properties added to the array or inherited from its prototype chain. For array values, use for...of; for array positions, use a counted for loop.

Condition-controlled loops: while and do…while

while checks first

let remaining = 3;
while (remaining > 0) {
  console.log(remaining);
  remaining--;
}

The condition is evaluated before the body. If it is false from the start, the body runs zero times. Use while when the number of passes depends on state that changes during the loop, such as a queue that is drained or a value that approaches a target.

do…while checks after the body

A do...while loop always executes its body once before the condition is tested. A common use is a retry that must make at least one attempt:

let attempts = 0;
let succeeded = false;

do {
  attempts++;
  succeeded = Math.random() > 0.5; // stand-in for a real operation
} while (!succeeded && attempts < 3);

console.log(`Stopped after ${attempts} attempt(s)`);

The first attempt happens unconditionally. The loop then stops either on success or after three attempts, whichever comes first.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choosing a loop

Need Use Why
Explicit counter, index, or custom step for Initialization, stop condition, and afterthought appear together.
Process each value in an iterable for...of It yields values without manual index handling.
Process enumerable object property keys for...in It iterates keys rather than iterable values.
Repeat while a condition holds, with zero passes possible while The condition is checked before the first pass.
Run once, then decide whether to repeat do...while The condition is checked after the body, so the first pass always happens.

Four questions separate these forms: which value the loop produces (index, key, or value), when the condition is checked, whether the body can run zero times, and whether you must maintain an index yourself.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Controlling execution with break and continue

  • break exits the loop immediately. Execution continues with the first statement after the loop.
  • continue ends the current pass and moves to the next one. In a counted for loop, it proceeds to the afterthought and then the condition check. In while and do...while, it proceeds directly to the condition check.
for (let i = 0; i < 6; i++) {
  if (i === 2) continue; // skip 2
  if (i === 4) break;    // stop before 4 is printed
  console.log(i);
}

This prints 0, 1, and 3. The value 2 is skipped, and the loop ends when it reaches 4, so 5 is never visited.

Common mistakes

  • Off-by-one bounds. With i <= names.length, the final pass reads names[names.length], which is past the last valid index and returns undefined at runtime. Use i < names.length for zero-based arrays.
  • Infinite loops. A while or do...while loop continues forever if its condition never becomes false and no break is reachable. Make sure something inside the body moves the state toward the exit condition, and check that a continue path does not skip the update that makes progress.
  • Using for…in for values. It returns keys, not elements, and on arrays it can include extra enumerable properties. Switch to for...of.

Closures and the loop counter

A let counter in a for loop gives each pass its own binding, so a callback captures the value from its own pass. A var counter is shared across the whole loop, so callbacks see its final value:

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i)); // logs 3, 3, 3
}

for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log(j)); // logs 0, 1, 2
}

In new TypeScript code, prefer let or const for loop variables.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Compilation targets and for…of

TypeScript compiles for...of differently depending on the target setting in tsconfig.json. The TypeScript handbook page “Iterators and Generators”, last updated October 5, 2026, documents two behaviors. For ES5 output, for...of over arrays is lowered to an indexed loop, and iterating other iterables such as Map or Set requires the downlevelIteration compiler option. For ES2015 and newer targets, the compiler emits native iterator code.

Before relying on for...of with non-array values in a project, check the target and downlevelIteration settings in that project’s configuration, and confirm the runtime supports the iteration you are using.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.