How to declare an Array of Objects in TypeScript

avatar

Borislav Hadzhiev

Fri Feb 25 20223 min read

Declare an Array of Objects in TypeScript #

To declare an array of objects in TypeScript, set the type of the variable to {}[], e.g. const arr: { name: string; age: number }[] = []. Once the type is set, the array can only contain objects that conform to the specified type, otherwise the type checker throws an error.

index.ts
// ✅ with inline type const arr: { name: string; age: number }[] = [ { name: 'Alice', age: 27 }, { name: 'Bob', age: 28 }, { name: 'Carl', age: 29 }, ]; // ✅ with existing Type or Interface interface Person { name: string; age: number; } const arr2: Person[] = [ { name: 'Alice', age: 27 }, { name: 'Bob', age: 28 }, { name: 'Carl', age: 29 }, ]; // ✅ array of objects with type, without values const arr3: { name: string; age: number }[] = [];

In the first example, we used an inline declaration to set the type of the arr variable to an array of objects. Each object contains a name property that is a string and an age property that is a number.

In the second example we used an interface to type a variable that stores an array of objects.

The third example shows to how initialize an empty array, but still set its type to be an array of objects.

If we try to add an object that doesn't conform to the specified type to the array, we'd get an error.

index.ts
const arr: { name: string; age: number }[] = [ { name: 'Alice', age: 27 }, { name: 'Bob', age: 28 }, { name: 'Carl', age: 29 }, ]; // ⛔️ Argument of type '{ hello: string; }' // is not assignable to parameter of // type '{ name: string; age: number; }'. arr.push({ hello: 'world' });

This is especially useful when you have to initialize the variable to an empty array. If you initialize a variable to an empty array and don't explicitly set its type, it is assumed to be any[].

index.ts
// 👇️ const arr3: any[] const arr3 = [];

It's a best practice to try to avoid any, so we can leverage the type checker.

Once we type the variable to be an array of objects of specific type, we get notified if we try to add an element to the array that does not conform to the type.

index.ts
const arr3: { name: string; age: number }[] = []; // ✅ Works arr3.push({ name: 'Alice', age: 30 }); // ⛔️ Error: Argument of type '{ hello: string; }' // is not assignable to parameter of type // '{ name: string; age: number; }' arr3.push({ hello: 'world' });

On the other hand, if you declare an array with values, you can let TypeScript infer the type of the array.

index.ts
// 👇️ const arr: {name: string; age: number;}[] const arr = [ { name: 'Alice', age: 27 }, { name: 'Bob', age: 28 }, { name: 'Carl', age: 29 }, ];

Even though we didn't explicitly type the arr variable, TypeScript already knows that it's an array of objects, where each object has a name property of type string and an age property of type number.

When declaring the type of an array of objects, you might not know the names of all of the object's keys or the type of its values in advance. If that's the case, you can use an index signature.

index.ts
interface Person { name: string; age: number; [key: string]: any; // 👈️ index signature } const arr2: Person[] = [ { name: 'Alice', age: 27 }, { name: 'Bob', age: 28, country: 'Chile' }, ]; arr2.push({ name: 'Carl', age: 30, country: 'Canada' });

An index signature is used when we don't know all the names of a type's properties and the shape of their values ahead of time.

The index signature in the examples means that when an the object is indexed with a string, it will return a value of any type.

You might also see the index signature {[key: string]: string} in examples. It represents a key-value structure that when indexed with a string returns a value of type string.

The Person interface in the example specifies that the object must have a name property that is a string and an age property that is a number, but it might have any other properties that are a string and their values might be of any type.

This approach is useful when you don't know the names of all of the keys in the object ahead of time.

It's always better to be as explicit as possible. You should always add the names and the types of the key-value pairs you know about.

This allows us to leverage the type checker as much as possible, which is the whole point of using TypeScript.

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