Iterating over an Object with forEach() in TypeScript

avatar

Borislav Hadzhiev

Sun Feb 27 20222 min read

banner

Photo by Toa Heftiba

Iterating over an Object with forEach() in TypeScript #

To iterate over an object with forEach() in TypeScript:

  1. Use the Object.entries() method to get an array of key-value pairs.
  2. Call the forEach() method on the array.
  3. The forEach() method will get called with an array containing a key-value pair on each iteration.
index.ts
const obj = { name: 'Tom', country: 'Chile', }; // ✅ forEach after Object.keys (Object.keys(obj) as (keyof typeof obj)[]).forEach((key, index) => { // 👇️ name Tom 0, country Chile 1 console.log(key, obj[key], index); }); // ✅ forEach after Object.entries (better) Object.entries(obj).forEach(([key, value], index) => { // 👇️ name Tom 0, country Chile 1 console.log(key, value, index); });

In the first example, we used the Object.keys method to get an array of the object's keys.

However, TypeScript sets the type of the return value of Object.keys() to string[].

index.ts
const obj = { name: 'Tom', country: 'Chile', }; // 👇️ string[] const result = Object.keys(obj); console.log(Object.keys(obj)); // 👉️ ['name', 'country']

Since not every string is a key in the object, we have to type the return value of Object.keys() before we are able to access object values by key.

We used keyof typeof to set the type of Object.keys() to an array containing keys of obj, so we can safely access its values.

index.ts
const obj = { name: 'Tom', country: 'Chile', }; // ✅ forEach after Object.keys (Object.keys(obj) as (keyof typeof obj)[]).forEach((key, index) => { // 👇️ name Tom 0, country Chile 1 console.log(key, obj[key], index); });

Had we not used the type assertion, we would get an error when trying to access a value in the object by key.

index.ts
const obj = { name: 'Tom', country: 'Chile', }; Object.keys(obj).forEach((key, index) => { // ⛔️ Error: No index signature with a parameter // of type 'string' was found on // type '{ name: string; country: string; }'. console.log(key, obj[key], index); });

TypeScript is telling us that key has a type of string and the object only has keys name and country, so we can't use any string to index the object.

A much cleaner approach is to use the Object.entries method.

index.ts
const obj = { name: 'Tom', country: 'Chile', }; // ✅ forEach after Object.entries Object.entries(obj).forEach(([key, value], index) => { // 👇️ name Tom 0, country Chile 1 console.log(key, value, index); });

The Object.entries() method returns an array of key-value pairs, on which we can call the forEach() method.

index.ts
const obj = { name: 'Tom', country: 'Chile', }; // 👇️ const result: [string, string][] const result = Object.entries(obj); // 👇️ [['name', 'Tom'], ['country', 'Chile']] console.log(result);

The forEach method gets passed an array containing 2 elements on each iteration - the key and the value.

We can use destructuring to get the key and value directly.

index.ts
const obj = { name: 'Tom', country: 'Chile', }; // ✅ forEach after Object.entries Object.entries(obj).forEach(([key, value], index) => { // 👇️ name Tom 0, country Chile 1 console.log(key, value, index); });

We used destructuring assignment in the function's parameter list.

This is very similar to the following line of code.

index.ts
const [key, value] = ['name', 'Tom']; console.log(key); // 👉️ "name" console.log(value); // 👉️ "Tom"

We are basically assigning the array elements to variables (the order is preserved).

Use the search field on my Home Page to filter through my more than 1,000 articles.