How to Work with Arrays of Objects in TypeScript

When I build a customer dashboard, support-ticket application, or sales-reporting tool, I often receive data as an array of objects. For example, an API may return a list of customers, orders, or employees instead of a single value.

TypeScript makes this easier to manage because it adds static type checking to JavaScript. You can define exactly what properties each object should contain and catch many mistakes before your code runs.

In this guide, you will learn how to create, access, search, update, filter, and transform arrays of objects in TypeScript with practical examples.

What Is an Array of Objects in TypeScript?

An array is an ordered collection of values. An object stores related information using properties and values.

An array of objects combines both concepts. For example, a sales application might store multiple customers like this:

const customers = [
    { id: 1, name: "John Smith", city: "New York" },
    { id: 2, name: "Emily Johnson", city: "Chicago" },
    { id: 3, name: "Michael Brown", city: "Dallas" }
];

console.log(customers);

Output:

[
  { id: 1, name: 'John Smith', city: 'New York' },
  { id: 2, name: 'Emily Johnson', city: 'Chicago' },
  { id: 3, name: 'Michael Brown', city: 'Dallas' }
]

This works, but TypeScript does not yet have an explicit reusable definition for a customer. In real projects, I recommend using an interface or a type.

You can also learn more about advanced object typing in TypeScript objects and advanced type safety.

Create an Array of Objects in TypeScript with an Interface

An interface defines the expected structure of an object. This improves type safety, which means TypeScript checks whether your data matches the expected structure.

interface Customer {
    id: number;
    name: string;
    city: string;
    isActive: boolean;
}

const customers: Customer[] = [
    {
        id: 1,
        name: "John Smith",
        city: "New York",
        isActive: true
    },
    {
        id: 2,
        name: "Emily Johnson",
        city: "Chicago",
        isActive: true
    },
    {
        id: 3,
        name: "Michael Brown",
        city: "Dallas",
        isActive: false
    }
];

console.log(customers);

Output:

[
  {
    id: 1,
    name: 'John Smith',
    city: 'New York',
    isActive: true
  },
  {
    id: 2,
    name: 'Emily Johnson',
    city: 'Chicago',
    isActive: true
  },
  {
    id: 3,
    name: 'Michael Brown',
    city: 'Dallas',
    isActive: false
  }
]

Here, Customer[] means an array where every item must follow the Customer interface.

If you accidentally add an object without a required property, TypeScript reports an error during development. This becomes especially useful when working with API responses or large applications.

For a detailed comparison, check TypeScript type vs interface.

How to Access Objects in a TypeScript Array

You can access an object using its array index.

interface Employee {
    id: number;
    name: string;
    department: string;
}

const employees: Employee[] = [
    { id: 101, name: "David Miller", department: "Sales" },
    { id: 102, name: "Sarah Wilson", department: "Marketing" },
    { id: 103, name: "Robert Davis", department: "Finance" }
];

console.log(employees[0]);
console.log(employees[0].name);
console.log(employees[1].department);

Output:

{ id: 101, name: 'David Miller', department: 'Sales' }
David Miller
Marketing

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

Work with Arrays of Objects in TypeScript

The first object has index 0, the second has index 1, and so on.

Accessing properties directly works well when you know the position. However, in real applications, I usually search by an ID instead because array positions can change.

Loop Through an Array of Objects in TypeScript

A loop lets you process each object in an array.

Using for…of

The for...of loop provides a clean way to access each object.

interface Product {
    id: number;
    name: string;
    price: number;
}

const products: Product[] = [
    { id: 1, name: "Laptop", price: 1200 },
    { id: 2, name: "Monitor", price: 350 },
    { id: 3, name: "Keyboard", price: 80 }
];

for (const product of products) {
    console.log(`${product.name}: $${product.price}`);
}

Output:

Laptop: $1200
Monitor: $350
Keyboard: $80

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

How to Work with Arrays of Objects in TypeScript

Each iteration stores the current object in the product variable. TypeScript automatically knows that product follows the Product interface.

Using forEach()

You can also use the forEach() array method.

interface Product {
    id: number;
    name: string;
    price: number;
}

const products: Product[] = [
    { id: 1, name: "Laptop", price: 1200 },
    { id: 2, name: "Monitor", price: 350 },
    { id: 3, name: "Keyboard", price: 80 }
];

products.forEach((product, index) => {
    console.log(`${index}: ${product.name}`);
});

Output:

0: Laptop
1: Monitor
2: Keyboard

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

Work with Arrays of Objects TypeScript

forEach() works well when you want to perform an action for every item but do not need to create a new array.

You may also find TypeScript forEach loop with index useful.

Find an Object in an Array of Objects in TypeScript

The find() method returns the first object that matches a condition. Imagine a support application where you need to find a ticket by its ID.

interface SupportTicket {
    id: number;
    title: string;
    status: string;
}

const tickets: SupportTicket[] = [
    { id: 1001, title: "Login issue", status: "Open" },
    { id: 1002, title: "Email not working", status: "In Progress" },
    { id: 1003, title: "Printer problem", status: "Closed" }
];

const ticket = tickets.find(ticket => ticket.id === 1002);

console.log(ticket);

Output:

{ id: 1002, title: 'Email not working', status: 'In Progress' }

find() returns one matching object. If it cannot find anything, it returns undefined. For safe handling, always check the result when the object may not exist.

interface SupportTicket {
    id: number;
    title: string;
    status: string;
}

const tickets: SupportTicket[] = [
    { id: 1001, title: "Login issue", status: "Open" },
    { id: 1002, title: "Email not working", status: "In Progress" }
];

const ticket = tickets.find(ticket => ticket.id === 9999);

if (ticket) {
    console.log(ticket.title);
} else {
    console.log("Ticket not found");
}

Output:

Ticket not found

This approach prevents errors when accessing properties on an undefined value. For related checks, see how to check if an object is undefined in TypeScript.

Filter an Array of Objects in TypeScript

The filter() method returns a new array containing all objects that match a condition.

For example, you may want to display only active customers.

interface Customer {
    id: number;
    name: string;
    city: string;
    isActive: boolean;
}

const customers: Customer[] = [
    { id: 1, name: "John Smith", city: "New York", isActive: true },
    { id: 2, name: "Emily Johnson", city: "Chicago", isActive: false },
    { id: 3, name: "Michael Brown", city: "Dallas", isActive: true }
];

const activeCustomers = customers.filter(
    customer => customer.isActive
);

console.log(activeCustomers);

Output:

[
  { id: 1, name: 'John Smith', city: 'New York', isActive: true },
  { id: 3, name: 'Michael Brown', city: 'Dallas', isActive: true }
]

The original customers array remains unchanged. filter() creates a new array. This makes it useful in frontend applications where you need to show filtered data without modifying the original API response.

Transform an Array of Objects with map()

The map() method creates a new array by transforming every item. Suppose you need only the names of your customers.

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

const customers: Customer[] = [
    { id: 1, name: "John Smith", city: "New York" },
    { id: 2, name: "Emily Johnson", city: "Chicago" },
    { id: 3, name: "Michael Brown", city: "Dallas" }
];

const customerNames: string[] = customers.map(
    customer => customer.name
);

console.log(customerNames);

Output:

[ 'John Smith', 'Emily Johnson', 'Michael Brown' ]

The original array contains Customer objects, while the new array contains strings. map() is useful when preparing API data for dropdowns, charts, reports, and user interfaces.

Add an Object to an Array in TypeScript

You can add an object with push().

interface Employee {
    id: number;
    name: string;
    department: string;
}

const employees: Employee[] = [
    { id: 101, name: "David Miller", department: "Sales" },
    { id: 102, name: "Sarah Wilson", department: "Marketing" }
];

employees.push({
    id: 103,
    name: "Robert Davis",
    department: "Finance"
});

console.log(employees);

Output:

[
  { id: 101, name: 'David Miller', department: 'Sales' },
  { id: 102, name: 'Sarah Wilson', department: 'Marketing' },
  { id: 103, name: 'Robert Davis', department: 'Finance' }
]

push() causes mutation, meaning it changes the existing array.\ If you want to keep the original array unchanged, use the spread operator instead.

interface Employee {
    id: number;
    name: string;
    department: string;
}

const employees: Employee[] = [
    { id: 101, name: "David Miller", department: "Sales" },
    { id: 102, name: "Sarah Wilson", department: "Marketing" }
];

const updatedEmployees: Employee[] = [
    ...employees,
    { id: 103, name: "Robert Davis", department: "Finance" }
];

console.log(updatedEmployees);
console.log(employees);

Output:

[
  { id: 101, name: 'David Miller', department: 'Sales' },
  { id: 102, name: 'Sarah Wilson', department: 'Marketing' },
  { id: 101, name: 'David Miller', department: 'Sales' },
  { id: 102, name: 'Sarah Wilson', department: 'Marketing' }
]

The first array is the new array, while the second output shows that employees remains unchanged.

Learn more about this syntax in TypeScript spread operator.

Pro Tip: I usually avoid mutating API data directly in frontend applications. Creating a new array with the spread syntax makes state changes easier to track and reduces unexpected bugs.

Update an Object in an Array of Objects

A common requirement is updating one object while keeping the rest unchanged. For example, a support-ticket application may need to change a ticket’s status.

interface SupportTicket {
    id: number;
    title: string;
    status: string;
}

const tickets: SupportTicket[] = [
    { id: 1001, title: "Login issue", status: "Open" },
    { id: 1002, title: "Email not working", status: "Open" },
    { id: 1003, title: "Printer problem", status: "Closed" }
];

const updatedTickets = tickets.map(ticket => {
    if (ticket.id === 1002) {
        return {
            ...ticket,
            status: "In Progress"
        };
    }

    return ticket;
});

console.log(updatedTickets);

Output:

[
  { id: 1001, title: 'Login issue', status: 'Open' },
  { id: 1002, title: 'Email not working', status: 'In Progress' },
  { id: 1003, title: 'Printer problem', status: 'Closed' }
]

This approach uses map() to create a new array. It also creates a new object for the updated ticket. That pattern works particularly well with React, state management, and API data processing.

For more details, see how to update an object in an array in TypeScript.

Sort an Array of Objects in TypeScript

You can use sort() to arrange objects based on a property.

interface Product {
    id: number;
    name: string;
    price: number;
}

const products: Product[] = [
    { id: 1, name: "Laptop", price: 1200 },
    { id: 2, name: "Keyboard", price: 80 },
    { id: 3, name: "Monitor", price: 350 }
];

const sortedProducts = [...products].sort(
    (a, b) => a.price - b.price
);

console.log(sortedProducts);

Output:

[
  { id: 2, name: 'Keyboard', price: 80 },
  { id: 3, name: 'Monitor', price: 350 },
  { id: 1, name: 'Laptop', price: 1200 }
]

The spread syntax creates an array copy before sorting because sort() changes the original array.

For object-specific sorting, read how to sort an array of objects by property value in TypeScript.

Remove an Object from an Array

You can use filter() to remove an object by excluding it.

interface Customer {
    id: number;
    name: string;
}

const customers: Customer[] = [
    { id: 1, name: "John Smith" },
    { id: 2, name: "Emily Johnson" },
    { id: 3, name: "Michael Brown" }
];

const updatedCustomers = customers.filter(
    customer => customer.id !== 2
);

console.log(updatedCustomers);

Output:

[
  { id: 1, name: 'John Smith' },
  { id: 3, name: 'Michael Brown' }
]

This creates a new array and keeps the original array unchanged. I prefer this approach in most modern TypeScript applications because it avoids unnecessary mutation.

Create a Generic Function for Arrays of Objects

A generic function is a reusable function that works with different types while preserving type information.

For example, you can create a reusable function to find an object by its ID.

interface Identifiable {
    id: number;
}

function findById<T extends Identifiable>(
    items: T[],
    id: number
): T | undefined {
    return items.find(item => item.id === id);
}

interface Employee extends Identifiable {
    name: string;
    department: string;
}

const employees: Employee[] = [
    { id: 101, name: "David Miller", department: "Sales" },
    { id: 102, name: "Sarah Wilson", department: "Marketing" }
];

const employee = findById(employees, 102);

console.log(employee);

Output:

{ id: 102, name: 'Sarah Wilson', department: 'Marketing' }

The <T extends Identifiable> syntax ensures that every object passed to the function has an id property.

At the same time, TypeScript preserves additional properties such as name and department. This is useful in reusable Node.js services, utility libraries, and larger applications.

Work with Nested Objects in an Array

Objects inside an array can also contain other objects.

interface Address {
    city: string;
    state: string;
}

interface Customer {
    id: number;
    name: string;
    address: Address;
}

const customers: Customer[] = [
    {
        id: 1,
        name: "John Smith",
        address: {
            city: "New York",
            state: "NY"
        }
    },
    {
        id: 2,
        name: "Emily Johnson",
        address: {
            city: "Chicago",
            state: "IL"
        }
    }
];

customers.forEach(customer => {
    console.log(`${customer.name} lives in ${customer.address.city}`);
});

Output:

John Smith lives in New York
Emily Johnson lives in Chicago

TypeScript checks the nested Address structure as well. This provides stronger protection when processing complex API responses.

Things to Keep in Mind

  • Use interfaces for structure: Define an interface when every object follows the same shape. This improves readability and type safety.
  • Watch for mutation: Methods such as push() and sort() change the original array. Create a copy first when you need immutable data.
  • Handle undefined from find(): The find() method may not locate a matching object. Always check the result before accessing its properties.
  • Use map() for transformations: Choose map() when you want a new array based on existing objects.
  • Use filter() for multiple matches: filter() returns all matching objects and also works well for removing items.
  • Avoid unnecessary copies for large arrays: Creating multiple copies consumes memory. For large backend datasets, choose your array operations carefully.

Frequently Asked Questions

How do I create an array of objects in TypeScript?

Define an interface for the object structure and use InterfaceName[] as the array type. This ensures every object follows the expected properties and types.

How do I find an object in an array in TypeScript?

Use the find() method with a condition. Remember that find() returns undefined when no matching object exists.

How do I filter an array of objects in TypeScript?

Use the filter() method and return a condition for each object. It creates a new array containing only the matching objects.

How do I update an object in an array in TypeScript?

Use map() to create a new array and return an updated object when the required condition matches. The spread syntax helps preserve existing object properties.

Can I use interfaces with arrays of objects?

Yes. This is one of the best ways to work with arrays of objects in TypeScript. Interfaces define the expected object structure and improve type safety.

Does map() change the original array in TypeScript?

No. map() returns a new array and does not change the original array. However, remember that object references can still matter if you directly modify nested objects.

Arrays of objects are fundamental when building real TypeScript applications because most APIs and business applications work with structured collections of data. By combining interfaces, find(), filter(), map(), loops, and the spread syntax, you can manage that data safely and clearly.

For most projects, I recommend defining a strong interface first and avoiding direct mutation unless you explicitly need it. 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.