How to Get Index in forEach Loop in TypeScript

When I build small reporting tools or customer dashboards, I often need more than the current array item. I also need its position. Maybe I want to show row numbers, flag the first customer, or create a numbered export for a sales team.

That is where the TypeScript forEach loop index becomes useful. The forEach() method gives you the current item and its zero-based index, which is the item’s position in the array.

You will see how to get index in forEach loop in TypeScript, work with typed objects, and choose a better loop when forEach() does not fit.

How to Get Index in forEach Loop in TypeScript

The simplest way to get the index in a forEach loop is to add a second parameter to its callback function.

A callback function runs once for every item in an array. The first parameter represents the current value. The second parameter represents the current index.

Here is the basic syntax:

array.forEach((value, index) => {
// Use value and index here
});

The index always starts at 0. So, the first item has index 0, the second item has index 1, and so on.

Basic forEach index example

Let’s use a small sales-reporting example. This TypeScript file loops through sales representative names and prints their position.

Create a file named foreach-index.ts:

const salesRepresentatives: string[] = [
"Emma Johnson",
"Daniel Miller",
"Olivia Davis"
];

salesRepresentatives.forEach((representative, index) => {
console.log(`Index ${index}: ${representative}`);
});

Run it in a Node.js project with TypeScript installed:

npx ts-node foreach-index.ts

Output:

Index 0: Emma Johnson
Index 1: Daniel Miller
Index 2: Olivia Davis

I executed the above example code and added the screenshot below.

Get Index in forEach Loop in TypeScript

The representative variable holds the current name. The index variable holds the array position. TypeScript infers that representative is a string and index is a number.

This pattern works in frontend development, backend APIs, browser applications, and automation scripts. If you are new to array methods, you may also find this guide on TypeScript forEach method on arrays helpful.

Use Index in forEach Loop in TypeScript With Objects

In real applications, arrays often contain objects instead of plain strings. For example, a customer dashboard may store each customer’s name, city, and monthly sales amount.

An interface defines the required shape of an object. It helps TypeScript catch mistakes before your code runs.

Number customer records

The following example prints a readable customer list with a one-based row number.

interface Customer {
name: string;
city: string;
monthlySales: number;
}

const customers: Customer[] = [
{
name: "Emma Johnson",
city: "Austin, Texas",
monthlySales: 12500
},
{
name: "Daniel Miller",
city: "Chicago, Illinois",
monthlySales: 9800
},
{
name: "Sophia Martinez",
city: "Miami, Florida",
monthlySales: 14300
}
];

customers.forEach((customer, index) => {
const rowNumber = index + 1;

console.log(
`${rowNumber}. ${customer.name} | ${customer.city} | $${customer.monthlySales}`
);
});

Output:

1. Emma Johnson | Austin, Texas | $12500
2. Daniel Miller | Chicago, Illinois | $9800
3. Sophia Martinez | Miami, Florida | $14300

I executed the above example code and added the screenshot below.

How to Get Index in forEach Loop in TypeScript

I add 1 to the index because people usually expect report rows to begin at 1. The actual array index still starts at 0.

This approach is useful when you render numbered records in a web application, prepare API response logs, or generate formatted terminal output. For more ways to work with structured values, see arrays of objects in TypeScript.

Pro Tip: I always keep the raw zero-based index separate from a display number. Use index for array logic and index + 1 only when showing data to users.

The Three forEach Callback Parameters

The forEach() callback accepts up to three parameters:

array.forEach((currentValue, index, array) => {
// Code here
});
  • currentValue is the item currently being processed.
  • index is the zero-based position of that item.
  • array is the original array that you called forEach() on.

You usually need only the first two. The third parameter helps when you need to compare an item with the full array.

Highlight the last customer

This example uses the index and array length to identify the final record in a customer report.

interface Customer {
name: string;
city: string;
}

const customers: Customer[] = [
{ name: "Emma Johnson", city: "Austin, Texas" },
{ name: "Daniel Miller", city: "Chicago, Illinois" },
{ name: "Sophia Martinez", city: "Miami, Florida" }
];

customers.forEach((customer, index, customerList) => {
const isLastCustomer = index === customerList.length - 1;
const label = isLastCustomer ? "Final customer" : "Customer";

console.log(`${label} at index ${index}: ${customer.name} from ${customer.city}`);
});

Output:

Customer at index 0: Emma Johnson from Austin, Texas
Customer at index 1: Daniel Miller from Chicago, Illinois
Final customer at index 2: Sophia Martinez from Miami, Florida

I executed the above example code and added the screenshot below.

Get Index in forEach Loop TypeScript

The expression customerList.length - 1 gives the final valid index. This works because an array with three items has a length of 3 but valid indexes from 0 through 2.

If you need to confirm array size before looping, read how to find the length of an array in TypeScript.

Get Index in forEach Loop With an Arrow Function

Most modern TypeScript projects use an arrow function with forEach(). An arrow function is a shorter way to write a function.

Here is the standard function syntax:

const cities: string[] = ["Austin", "Chicago", "Seattle"];

cities.forEach(function (city, index) {
console.log(`${index}: ${city}`);
});

Output:

0: Austin
1: Chicago
2: Seattle

Here is the arrow function version:

const cities: string[] = ["Austin", "Chicago", "Seattle"];

cities.forEach((city, index) => {
console.log(`${index}: ${city}`);
});

Output:

0: Austin
1: Chicago
2: Seattle

Both versions produce the same result. I use arrow functions in most TypeScript code because they are compact and fit naturally with modern application code.

Use the Index to Update Another Array

A common use case involves building a new array from a source array. You might receive customer data from an API, then create display-ready labels for a report.

While forEach() does not return a new array, you can create one before the loop and add values with push().

Create numbered customer labels

interface Customer {
name: string;
city: string;
}

const customers: Customer[] = [
{ name: "Emma Johnson", city: "Austin, Texas" },
{ name: "Daniel Miller", city: "Chicago, Illinois" },
{ name: "Sophia Martinez", city: "Miami, Florida" }
];

const customerLabels: string[] = [];

customers.forEach((customer, index) => {
const label = `Customer ${index + 1}: ${customer.name} (${customer.city})`;
customerLabels.push(label);
});

console.log(customerLabels);

Output:

[
'Customer 1: Emma Johnson (Austin, Texas)',
'Customer 2: Daniel Miller (Chicago, Illinois)',
'Customer 3: Sophia Martinez (Miami, Florida)'
]

This code uses a typed string[] array so TypeScript only allows string values in customerLabels. That gives you better type safety than using any.

For cases where you only want a transformed array, map() usually communicates your intent more clearly than forEach(). The same index parameter works with map().

interface Customer {
name: string;
city: string;
}

const customers: Customer[] = [
{ name: "Emma Johnson", city: "Austin, Texas" },
{ name: "Daniel Miller", city: "Chicago, Illinois" },
{ name: "Sophia Martinez", city: "Miami, Florida" }
];

const customerLabels: string[] = customers.map((customer, index) => {
return `Customer ${index + 1}: ${customer.name} (${customer.city})`;
});

console.log(customerLabels);

Output:

[
'Customer 1: Emma Johnson (Austin, Texas)',
'Customer 2: Daniel Miller (Chicago, Illinois)',
'Customer 3: Sophia Martinez (Miami, Florida)'
]

Use forEach() when you want a side effect, such as logging data, updating a variable, or calling a function. Use map() when you want a new array.

How to Get Index in forEach Loop in TypeScript Safely

TypeScript gives you the strongest benefits when you define the data shape instead of relying on any. An API integration can return missing or unexpected values, so use optional properties and safe fallback values when needed.

Handle optional data with the index

This example simulates customer records that may not include a city.

interface Customer {
name: string;
city?: string;
monthlySales: number;
}

const customers: Customer[] = [
{
name: "Emma Johnson",
city: "Austin, Texas",
monthlySales: 12500
},
{
name: "Daniel Miller",
monthlySales: 9800
},
{
name: "Sophia Martinez",
city: "Miami, Florida",
monthlySales: 14300
}
];

customers.forEach((customer, index) => {
const city = customer.city ?? "Location not provided";

console.log(
`Record ${index + 1}: ${customer.name} | ${city} | $${customer.monthlySales}`
);
});

Output:

Record 1: Emma Johnson | Austin, Texas | $12500
Record 2: Daniel Miller | Location not provided | $9800
Record 3: Sophia Martinez | Miami, Florida | $14300

The ? in city?: string marks city as optional. The ?? operator uses the fallback text only when city is null or undefined.

This protects a dashboard or automation script from showing an unclear value or failing when external data lacks an expected field. You can learn more about undefined and null in TypeScript when handling incomplete API data.

When Not to Use forEach for Indexes

The forEach() method looks clean, but it has limits. It does not return a value, and you cannot use break or continue inside it like a traditional loop.

Choose a regular for loop when you need to stop early, skip records, or await each asynchronous task in order.

Stop when a target customer is found

Suppose a local automation script searches a list for a specific customer. A for loop lets you stop as soon as you find the correct record.

interface Customer {
name: string;
city: string;
}

const customers: Customer[] = [
{ name: "Emma Johnson", city: "Austin, Texas" },
{ name: "Daniel Miller", city: "Chicago, Illinois" },
{ name: "Sophia Martinez", city: "Miami, Florida" }
];

const targetName = "Daniel Miller";

for (let index = 0; index < customers.length; index++) {
const customer = customers[index];

if (customer.name === targetName) {
console.log(`Found ${customer.name} at index ${index} in ${customer.city}.`);
break;
}
}

Output:

Found Daniel Miller at index 1 in Chicago, Illinois.

Use this pattern when performance matters and you want to stop processing immediately. For more loop choices, explore TypeScript for loops with arrays and for…of loops in TypeScript.

Avoid async/await inside forEach

A frequent mistake involves using an async callback inside forEach(). The loop does not wait for each promise to finish.

interface Customer {
name: string;
}

const customers: Customer[] = [
{ name: "Emma Johnson" },
{ name: "Daniel Miller" }
];

async function sendReport(customer: Customer, index: number): Promise<void> {
await new Promise<void>((resolve) => {
setTimeout(resolve, 100);
});

console.log(`Sent report ${index + 1} to ${customer.name}`);
}

async function processReports(): Promise<void> {
for (let index = 0; index < customers.length; index++) {
await sendReport(customers[index], index);
}
}

processReports();

Output:

Sent report 1 to Emma Johnson
Sent report 2 to Daniel Miller

This for loop waits for each report before moving to the next customer. That matters when requests must happen in sequence, such as rate-limited API calls or ordered file processing.

Things to Keep in Mind

  • Indexes start at zero: Add 1 only for user-facing row numbers or labels.
  • Use clear parameter names: Prefer customer and index over vague names like item and i in business code.
  • Do not modify the array: Avoid adding or removing items from the same array while forEach() runs, because it makes behavior harder to predict.
  • Keep strong types: Define an interface or type for object arrays instead of using any.
  • Use map for transformations: Choose map() when you need a new array, and use forEach() for logging or other side effects.
  • Avoid async forEach callbacks: Use for...of or a standard for loop when each async operation must finish before the next starts.

Frequently Asked Questions

How do I get the index in TypeScript forEach?

Add the index as the second parameter in the forEach() callback. Use items.forEach((item, index) => { … }), where index starts at 0.

Does forEach index start at 0 or 1 in TypeScript?

The index starts at 0 because TypeScript arrays use zero-based indexing. Use index + 1 when you need a human-friendly number.

Can I use index and value together in TypeScript forEach?

Yes. The first callback parameter is the value, and the second is the index. For example, customers.forEach((customer, index) => console.log(index, customer.name)).

Can I break out of a TypeScript forEach loop?

No, break does not work inside forEach(). Use a standard for loop or for...of loop when you need to stop early.

Can I use async/await with forEach in TypeScript?

You can mark the callback as async, but forEach() will not wait for the promises. Use a for...of loop or for loop when you need sequential async processing.

What type does the forEach index have in TypeScript?

TypeScript infers the index as a number. You normally do not need to add a type annotation yourself.

Getting the index in a TypeScript forEach() loop is as simple as adding the second callback parameter, then using it for row numbers, comparisons, logs, and display labels. Start with forEach() for straightforward array work, then move to map() or a regular loop when your code needs a returned array, early exit, or sequential async logic. I hope you found this article helpful.

You May Also Like

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.