How to Use for…of Loops in TypeScript

When I build sales dashboards or Node.js data-processing scripts, I often need to process every record returned from an API. A for…of loop gives me a clean way to work through each item without manually managing an array index.

The for…of loop works especially well when the value matters more than its position. TypeScript adds compile-time type checking, so the variable inside the loop gets the correct type automatically.

In this guide, I’ll show you how to use for…of loops in TypeScript with arrays, objects, strings, maps, readonly data, and real dashboard-style records.

What Is a for…of Loop in TypeScript?

A for…of loop iterates through the values in an iterable object. An iterable is a value that TypeScript and JavaScript can step through one item at a time, such as an array, string, Set, or Map.

Here is the basic syntax:

for (const item of collection) {
// Use item here
}

The loop runs once for every value in collection. The item variable holds the current value during each iteration.

Let’s start with a simple array of sales regions:

const regions: string[] = ["North", "South", "East", "West"];

for (const region of regions) {
console.log(`Processing ${region} region`);
}

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

Use for...of Loops in TypeScript

This code prints each region one at a time. TypeScript understands that region is a string because the regions array has the string[] type annotation.

You do not need to write let index = 0, check the array length, or access regions[index]. That makes for…of easier to read than a traditional loop when you only need the values.

For more ways to work with typed lists, see how to iterate over arrays in TypeScript.

Why Use for…of Loops in TypeScript?

I use for...of when I need clear, predictable code that processes every item in a collection. It keeps the focus on the actual record instead of loop bookkeeping.

A traditional for loop still helps when you need an index or want to skip through an array in fixed increments. However, for...of is usually the better starting point for API results, dashboard rows, form values, and automation output.

Here is a comparison:

const monthlySales: number[] = [1200, 1850, 2100];

for (let index = 0; index < monthlySales.length; index++) {
console.log(monthlySales[index]);
}

The same code becomes simpler with for...of:

const monthlySales: number[] = [1200, 1850, 2100];

for (const sale of monthlySales) {
console.log(sale);
}

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

for...of Loops in TypeScript

Both loops produce the same JavaScript behavior at runtime. TypeScript does not change how JavaScript loops execute. Instead, it checks your types before compilation and helps catch mistakes in your editor.

If you need index-based logic, read how to use TypeScript for loops with arrays.

Use for…of Loops in TypeScript Arrays

A typed array is the most common place to use a for...of loop. In a real application, this could be a list of tasks, products, customer records, or API response items.

Let’s use a sales dashboard example.

interface SalesRecord {
id: number;
representative: string;
amount: number;
isClosed: boolean;
}

const salesRecords: SalesRecord[] = [
{ id: 101, representative: "Asha", amount: 14500, isClosed: true },
{ id: 102, representative: "Ravi", amount: 8200, isClosed: false },
{ id: 103, representative: "Meera", amount: 17600, isClosed: true }
];

for (const record of salesRecords) {
console.log(`${record.representative}: ${record.amount}`);
}

The SalesRecord interface describes the shape of every object in the array. TypeScript knows that record.amount is a number and record.representative is a string.

That protection matters when you process API data. If you accidentally write record.customerName, TypeScript flags the error because that property does not exist on SalesRecord.

Calculate a total with for…of

A loop often needs to build a result, such as a revenue total.

let totalRevenue: number = 0;

for (const record of salesRecords) {
totalRevenue += record.amount;
}

console.log(totalRevenue); // 40300

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

How to Use for...of Loops in TypeScript

The totalRevenue variable starts at zero. Each loop iteration adds the current record’s amount. This pattern works well when you need custom conditions or extra logging that would make an array method like reduce() harder to follow.

Filter records while looping

You can use an if statement inside a for...of loop to process only matching records.

const closedDeals: SalesRecord[] = [];

for (const record of salesRecords) {
if (record.isClosed) {
closedDeals.push(record);
}
}

console.log(closedDeals);

This code creates a new array instead of changing salesRecords. That makes the result easier to reuse in a dashboard, report, or UI component.

Pro Tip: I have found that keeping the original API array unchanged prevents confusing bugs when one list feeds several dashboard widgets. Create a separate result array when you need filtered or transformed data.

For a more functional approach, you can also use filter arrays in TypeScript.

Use for…of Loops in TypeScript Strings

Strings are iterable, so a for...of loop can process one character at a time. This is useful for validation, formatting checks, and lightweight text parsing.

For example, a dashboard might accept a short sales code that contains letters and numbers.

const salesCode: string = "Q3-IND-2026";

for (const character of salesCode) {
console.log(character);
}

Each character is a string. The loop includes hyphens because they are part of the original text.

Here is a practical validation example that checks whether a code contains a digit:

const salesCode: string = "Q3-IND-2026";
let hasDigit: boolean = false;

for (const character of salesCode) {
if (character >= "0" && character <= "9") {
hasDigit = true;
break;
}
}

console.log(hasDigit); // true

The break statement stops the loop as soon as it finds a digit. This saves unnecessary work and makes the purpose clear. Learn more in this guide on the break statement in TypeScript for loops.

Use for…of Loops with Maps and Sets

Set stores unique values. A Map stores key-and-value pairs. Both work with for...of.

Loop through a Set

Use a Set when you need unique values, such as the regions represented in a sales report.

const activeRegions: Set<string> = new Set([
"North",
"South",
"North",
"East"
]);

for (const region of activeRegions) {
console.log(region);
}

The output includes NorthSouth, and East only once. The Set removes duplicate values when you create it.

Loop through a Map

Use a Map when you need a key connected to a value.

const revenueByRegion: Map<string, number> = new Map([
["North", 24500],
["South", 18200],
["East", 21900]
]);

for (const [region, revenue] of revenueByRegion) {
console.log(`${region}: ${revenue}`);
}

The square brackets use array destructuring. Each Map entry contains two values: the key and the value. TypeScript infers region as a string and revenue as a number.

This is a clean pattern for grouped API data, configuration values, and data aggregation tasks.

Use for…of Loops with Readonly Arrays

A readonly array prevents you from changing the array through that variable. It protects shared data from accidental push()pop(), or splice() operations.

You can still read every item with for...of.

const reportPeriods: readonly string[] = [
"January",
"February",
"March"
];

for (const period of reportPeriods) {
console.log(`Generating report for ${period}`);
}

This loop works because it only reads values. TypeScript blocks code that tries to modify reportPeriods.

// reportPeriods.push("April");
// Error: Property 'push' does not exist on type 'readonly string[]'.

A readonly array is useful when a function receives data that it must not alter.

function printSalesRepresentatives(
records: readonly SalesRecord[]
): void {
for (const record of records) {
console.log(record.representative);
}
}

The function can safely inspect every record, but it cannot accidentally add or remove records. Read more about readonly arrays in TypeScript.

Get the Index in a for…of Loop

A standard for...of loop gives you the value, not its index. When you need both, use the entries() method.

const salesRepresentatives: string[] = ["Asha", "Ravi", "Meera"];

for (const [index, representative] of salesRepresentatives.entries()) {
console.log(`${index}: ${representative}`);
}

This produces:

0: Asha
1: Ravi
2: Meera

The entries() method returns each array item as a pair: [index, value]. Destructuring separates the pair into useful variables.

I use this approach when I need to show row numbers, build ordered labels, or report which API item caused a problem. For more examples, see how to get the index in a forEach loop in TypeScript.

Skip or Stop Items Safely

You can control a for...of loop with continue and break.

Use continue when you want to skip the current item but keep processing later items.

for (const record of salesRecords) {
if (!record.isClosed) {
continue;
}

console.log(`Closed deal: ${record.representative}`);
}

This loop ignores open deals and prints only closed deals. The continue statement keeps conditional logic flatter and easier to scan.

Use break when you have found what you need.

let firstLargeDeal: SalesRecord | undefined;

for (const record of salesRecords) {
if (record.amount > 15000) {
firstLargeDeal = record;
break;
}
}

console.log(firstLargeDeal);

The SalesRecord | undefined union type accurately represents both possible outcomes. The loop might find a large deal, or it might finish without finding one.

Things to Keep in Mind

  • Use const for loop values: The loop variable normally represents the current item, so const prevents accidental reassignment.
  • Remember runtime behavior: TypeScript checks types during compilation, but it does not validate untrusted API data at runtime.
  • Do not use for…in for arrays: for...in iterates property names or indexes, while for...of iterates actual values.
  • Avoid mutating shared records: Changing an object inside a loop changes that object everywhere it has been referenced.
  • Use entries() for indexes: A plain for...of loop provides values only, so use array.entries() when you need both index and value.
  • Choose array methods when appropriate: Use map()filter(), or reduce() for simple transformations, but use for...of when the processing includes several steps, conditions, or early exits.

Frequently Asked Questions

Can I use for…of with an object in TypeScript?

Not directly with a plain object because normal objects are not iterable. Use Object.keys()Object.values(), or Object.entries() first. You can also review how to iterate over objects in TypeScript.

What is the difference between for…of and for…in in TypeScript?

for...of returns values from an iterable, such as array items or string characters. for...in returns property keys, including array indexes as strings. Use for...of for arrays in most application code.

Can I use async/await inside a for…of loop?

Yes. A for...of loop works well with await when tasks must run in sequence. This is useful when each API call depends on the result of the previous call.

Does for…of work with readonly arrays?

Yes. A for...of loop only reads each value, so it works with a readonly array. TypeScript prevents mutations, but it allows safe iteration.

How do I skip an item in a TypeScript for…of loop?

Use the continue statement inside a condition. It stops the current iteration and immediately moves to the next item. See this guide on the continue statement in TypeScript for loops.

When should I use for…of instead of forEach()?

Use for...of when you need breakcontinue, or await. The forEach() method does not support breaking early, and it does not wait for asynchronous callbacks in the same clear sequence.

for...of loop gives you a simple, readable way to process typed arrays, strings, sets, maps, and readonly data in TypeScript. Start with it when you need clear item-by-item logic, then use entries()breakcontinue, or array methods when your requirements grow. 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.