How to Use the TypeScript forEach Method on Arrays

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
Command Prompt output of the TypeScript forEach method listing orders with their index, city and total, then the revenue
Three orders print with 1-based numbers and dollar totals, the revenue line adds them up, and only orders over $100 get free shipping.

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[]'.
Command Prompt showing TypeScript error TS2322 type void is not assignable to type number array when assigning forEach
The compiler reports that void isn’t assignable to 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' ]
Command Prompt output showing TypeScript forEach not awaiting async callbacks, compared with for...of and Promise.all
“forEach finished?” prints before any order ships, and the forEach results arrive out of order; for…of and Promise.all keep the order.

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
Command Prompt output of TypeScript Map.forEach with value then key, Set.forEach with unique states, and forEach skipping array holes
Each product shows its stock or sold out, the Set lists TX, CO and FL once, and the sparse array gets two callbacks for three slots.

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

NeedUse
Run code for each itemforEach() or for...of
Stop early with breakfor...of
Await each itemfor...of with await
Build a new arraymap()
Keep matching itemsfilter()
One value from manyreduce()

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:

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?