This the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

For

test

TypeScript supports three looping constructs:

Iterating over collections of something is such a common programming task, you will often find yourself using the for..of loop.

You’ll find yourself using the classic for loop mostly in situations where its syntax streamlines access to a loop counter that’s essential to your code implementation.

You will rarely need to iterate over an object’s properties, but when you do, you’ll see that you can still use a for..of loop instead of the more nuanced, legacy for..in loop.

1 - For loop

Classic for loop

All three “initialization/test/update” parts used.

for (let j = 4; j < 10; j++) {
  console.log(j);
}
  
4
5
6
7
8
9
  

Basic for loop

No initialization or update parts; only the test condition in the middle part (between the two semi-colons (;)).

let i = 1;

for (; i <= 3;) {
  console.log(i);
  i++;
}
  
1
2
3
  

For loop that only exits with break or return

This for loop will continuously “spin” unless it reaches a break or return statement, usually based on some condition to wait on that’s easier to specify in the loop body. Shown for completeness, but avoid doing this in normal code.

for (;;) {
  console.log("loop");
  break;
}
  
loop
  

For loop with continue

This for loop will conditionally continue to the next iteration of the loop, bypassing any remaining statements in the loop body.

for (let n = 0; n <= 5; n++) {
  if (n % 2 == 0) continue;
  console.log(n);
}
  
1
3
5
  

2 - For..of loop

The for..of loop is for looping over objects that implement the Iterable interface (expose a Symbol.iterator property).

In this section we’ll demonstrate iterating over:

2.1 - Iterating over a string

const str = "hello";

for (const s of str) {
  console.log(s, typeof s);
}
  
h string
e string
l string
l string
o string
  

2.2 - Iterating over an array

const nums = [2, 3, 4];

let sum = 0;

// Use `let i` because i mutates (`i++`).
for (let i = 0; i < nums.length; i++) {
  sum += nums[i];
}

console.log(`sum: ${sum}`);
  
sum: 9
  

2.3 - Iterating over a set

const set = new Set([2, 2, 3, 3, 4, 4]);

for (const val of set) {
  console.log(val);
}
  
2
3
4
  

2.4 - Iterating over a map

Iterate over map entries as key,value tuples.

const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);

for (const entry of map) {
  console.log(entry);
}
  
[ "a", 1 ]
[ "b", 2 ]
[ "c", 3 ]
  

Iterate over the map, accessing the key and value parts as variables.

const map = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (const [k, v] of map) {
  console.log(`key: ${k} => value: ${v}`);
}
  
key: a => value: 1
key: b => value: 2
key: c => value: 3
  

Iterate over just keys.

const map = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (const [key] of map) {
  console.log(`key: ${key}`);
}
  
key: a
key: b
key: c
  

Iterate over just the values. Note that a placeholder is required for each key, as designated by the underscore (_).

const map = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (const [_, value] of map) {
  console.log(`value: ${value}`);
}
  
value: 1
value: 2
value: 3
  

3 - For..in loop

The for..in loop is used to iterate over an object’s properties. Its classic usage with JavaScript has complex behavior that can be surprising, but as long as you use TypeScript, you avoid the nuances of JavaScript’s object-based inheritance and object prototype chaining.

Here we demonstrate the for..in loop, followed by the equivalent example using the for..of loop discussed in the previous section. Our recommendation is that you focus on using the for..of loop to keep things simple.

Iterating object properties with for..in

This example will use code that has not been discussed yet. The main point of this example right now is just to highlight the for..in and for..of loops with objects.

class A {
  foo = "base-value";
}

class B extends A {
  bar = "derived-value";
}

const b = new B();

for (const prop in b) {
  console.log(prop, "=", b[prop as keyof B]);
}
  
foo = base-value
bar = derived-value
  

There are two things to note about the output:

  • Looping over an object’s properties enumerates all of the properties in the inheritance chain. This normally what you want (and this is different from iterating over the prototype chain when using classic JavaScript object-based inheritance, which might or might not be what you want).

  • Because TypeScript is strongly typed, you have to cast each element of the enumeration to an indexed access type using keyof for the type.

Iterating object properties with for..of

There’s an easier way to do this. Simply use the for..of loop discussed in the previous section. The object itself (b) is not directly iterable, but you can get an iterator using Object.entries(b), as shown here:

class A {
  foo = "base-value";
}

class B extends A {
  bar = "derived-value";
}

const b = new B();

for (const [key, value] of Object.entries(b)) {
  console.log(key, "=", value);
}
  
foo = base-value
bar = derived-value
  

If you want to iterate only over an object’s keys or its values, you can use Object.keys() or Object.values(), respectively, instead of Object.entries().