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:
- The initialization runs once, before the first pass.
let i = 0creates the counter. - The condition is checked before every pass. When it evaluates to false, the loop stops.
- The body runs.
- 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.
Recommended Free Tools
Counting down or using a custom step
The afterthought can be any expression, so the same structure handles reverse order and larger steps:
#1 Best Overall
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 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:
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.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteChoosing 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.
Best Value
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
forloop, it proceeds to the afterthought and then the condition check. Inwhileanddo...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 readsnames[names.length], which is past the last valid index and returnsundefinedat runtime. Usei < names.lengthfor zero-based arrays. - Infinite loops. A
whileordo...whileloop continues forever if its condition never becomes false and nobreakis reachable. Make sure something inside the body moves the state toward the exit condition, and check that acontinuepath 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.
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.
Quick Recap
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.

