The TypeScript forEach method calls a function once for every element of an array: orders.forEach((order, index) => { ... }). TypeScript infers the element type for the callback, and forEach always returns void, so use it for side effects such as logging or totals:
orders.forEach((order, index) => console.log(index, order.city));
My setup for these examples: TypeScript 7.0.2 and Node.js v22.22.2, compiled with the strict flag. The console output is pasted as it came out.
You’ll see the callback parameters, why you can’t collect results from forEach, how return behaves, the async/await trap, and forEach on Map and Set.
Use the forEach method on an array of objects
The callback gets the element, its index and the whole array. You don’t annotate them; TypeScript reads the types from the array:
interface Order {
id: number;
city: string;
total: number;
}
const orders: Order[] = [
{ id: 2041, city: "Austin", total: 129.99 },
{ id: 2042, city: "Denver", total: 54.5 },
{ id: 2043, city: "Boston", total: 210.0 },
];
let revenue = 0;
orders.forEach((order, index) => { // order: Order, index: number (inferred)
revenue += order.total;
console.log(`${index + 1}. #${order.id} ${order.city.padEnd(7)} $${order.total.toFixed(2)}`);
});
console.log(`Revenue: $${revenue.toFixed(2)}`);
orders.forEach((order) => {
if (order.total < 100) return; // skips this one, like continue
console.log("Free shipping:", order.id);
});
Output:
1. #2041 Austin $129.99
2. #2042 Denver $54.50
3. #2043 Boston $210.00
Revenue: $394.49
Free shipping: 2041
Free shipping: 2043

return inside the callback only ends that one call, so it acts like continue. There’s more on the second parameter in getting the index in a forEach loop.
Why does forEach return undefined in TypeScript?
forEach throws away whatever the callback returns. Assigning its result to an array is a compile error in strict mode:
const prices: number[] = [19.99, 5.25, 102];
const withTax: number[] = prices.forEach((p) => p * 1.0825);
Output:
foreach_void.ts(3,7): error TS2322: Type 'void' is not assignable to type 'number[]'.

When you want a new array, use map(); when you want some items, use filter(). A single total is a job for the TypeScript array reduce method.
And there’s no way to stop a forEach early: break is a syntax error inside the callback. The workarounds are in breaking out of a forEach loop in TypeScript.
Does forEach wait for async functions?
No. forEach starts every async callback and moves on without waiting for any of them. Watch the order of the output:
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
async function shipOrder(id: number): Promise<string> {
await wait(50 * (4 - (id % 3))); // each order takes a different time
return `shipped #${id}`;
}
const ids = [3001, 3002, 3003];
async function main(): Promise<void> {
console.log("--- forEach (not awaited) ---");
ids.forEach(async (id) => console.log(await shipOrder(id)));
console.log("forEach finished?");
await wait(400);
console.log("--- for...of with await (in order) ---");
for (const id of ids) {
console.log(await shipOrder(id));
}
console.log("--- Promise.all (in parallel) ---");
const results = await Promise.all(ids.map(shipOrder));
console.log(results);
}
main();
Output:
--- forEach (not awaited) ---
forEach finished?
shipped #3002
shipped #3001
shipped #3003
--- for...of with await (in order) ---
shipped #3001
shipped #3002
shipped #3003
--- Promise.all (in parallel) ---
[ 'shipped #3001', 'shipped #3002', 'shipped #3003' ]

Use for...of with await to run one at a time, or Promise.all(ids.map(...)) to run them together. Both are explained in for…of loops in TypeScript.
Use forEach on a Map, a Set and sparse arrays
Maps and Sets have their own forEach. Note the Map callback gets the value first and the key second:
const stock = new Map<string, number>([["Mug", 12], ["Filters", 0], ["Beans", 40]]);
stock.forEach((qty, product) => { // value first, then key
console.log(`${product.padEnd(8)} ${qty > 0 ? qty + " in stock" : "sold out"}`);
});
const states = new Set(["TX", "CO", "TX", "FL"]);
states.forEach((s) => console.log("state:", s));
const sparse = [1, , 3]; // hole at index 1
let calls = 0;
sparse.forEach(() => calls++);
console.log("callbacks for", sparse.length, "slots:", calls);
Output:
Mug 12 in stock
Filters sold out
Beans 40 in stock
state: TX
state: CO
state: FL
callbacks for 3 slots: 2

Holes in an array are skipped entirely, while undefined values are not. For building a Map in the first place, see creating a Map from an array.
forEach vs for…of vs map
| Need | Use |
|---|---|
| Run code for each item | forEach() or for...of |
Stop early with break | for...of |
| Await each item | for...of with await |
| Build a new array | map() |
| Keep matching items | filter() |
| One value from many | reduce() |
I pick forEach for short side-effect callbacks and for...of for anything longer. A full comparison of loop styles is in iterating over arrays in TypeScript.
Related array tutorials on the site:
- Filter arrays in TypeScript
- Use the for loop in TypeScript
- Continue statement in TypeScript for loops
- Work with arrays of objects in TypeScript
Frequently asked questions
How do I use forEach in TypeScript?
Call array.forEach((item, index) => { ... }). TypeScript infers the type of item from the array.
What does forEach return?
Always undefined (typed void). Use map() to build a new array.
Can I break out of a forEach loop?
No. return only skips the current item. Use for...of, some() or find() when you need to stop.
Why doesn’t forEach wait for await?
forEach ignores the promises your async callback returns. Use for...of with await or Promise.all().
What order are the arguments in Map.forEach?
Value first, then key, then the map: map.forEach((value, key) => ...).
Where is Array.prototype.forEach documented?
See Array.prototype.forEach() on MDN.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn