How to Filter an Array of Objects by Multiple Properties in TypeScript?

Recently, in one of my TypeScript projects, I got a requirement to filter an array of objects by multiple properties. I researched about it. In this tutorial, I will explain how to filter an array of objects based on multiple property values in TypeScript.

Filter an Array of Objects by Multiple Properties in TypeScript

Let’s say you have an array of objects in TypeScript containing data about customers, like this:

const customers = [
  { id: 1, name: "John Smith", state: "CA", age: 25 },
  { id: 2, name: "Sarah Johnson", state: "NY", age: 32 }, 
  { id: 3, name: "Michael Lee", state: "CA", age: 19 },
  { id: 4, name: "Emily Davis", state: "TX", age: 27 }
];

You may want to filter this customers array to only those who live in California and are over 21 years old. Filtering allows you to extract a subset of objects matching specific conditions from a larger array.

Using the filter() Method In TypeScript and JavaScript, you can use the built-in filter() method to create a new array containing only elements that pass a provided test function. Here’s the basic syntax:

const filteredArray = originalArray.filter(callbackFn);

The callback function you pass to filter() gets called once for each element in the original array. It should return true to keep the element in the filtered array or false to exclude it.

Check out Get Unique Values from an Array of Objects in TypeScript

Filter An Array of Objects by a Single Property in TypeScript

To start, let’s filter the customers array to only those who live in California by checking the state property:

const customers = [
  { id: 1, name: "John Smith", state: "CA", age: 25 },
  { id: 2, name: "Sarah Johnson", state: "NY", age: 32 }, 
  { id: 3, name: "Michael Lee", state: "CA", age: 19 },
  { id: 4, name: "Emily Davis", state: "TX", age: 27 }
];
const caCustomers = customers.filter(customer => {
  return customer.state === "CA";
});

console.log(caCustomers);
/*
[
  { id: 1, name: "John Smith", state: "CA", age: 25 },
  { id: 3, name: "Michael Lee", state: "CA", age: 19 } 
]
*/

The filter callback function checks each customer object and returns true only if the state property equals “CA”. This gives us a new array caCustomers containing only the matching California customers.

Here is the exact output in the screenshot below:

Filter an Array of Objects by Multiple Properties in TypeScript

Check out Remove Duplicates from an Array of Objects in TypeScript

Filter an Array of Objects by Multiple Properties in TypeScript

To filter on multiple property values, we can extend our test function to check each desired criteria. Let’s filter for California customers over 21 years old:

const customers = [
    { id: 1, name: "John Smith", state: "CA", age: 25 },
    { id: 2, name: "Sarah Johnson", state: "NY", age: 32 }, 
    { id: 3, name: "Michael Lee", state: "CA", age: 19 },
    { id: 4, name: "Emily Davis", state: "TX", age: 27 }
  ];
  const caOver21 = customers.filter(customer => {
    return customer.state === "CA" && customer.age >= 21;
  });
  
  console.log(caOver21); 
/*
[
  { id: 1, name: "John Smith", state: "CA", age: 25 }
]
*/

Now the callback returns true only if both conditions are met – state is “CA” and age is greater than or equal to 21. The resulting caOver21 array contains only the objects matching both criteria.

Here is the exact output in the screenshot below:

TypeScript Filter an Array of Objects by Multiple Properties

You can add additional property checks to filter on as many values as needed:

const filteredCustomers = customers.filter(c => {
  return c.state === "CA" 
    && c.age >= 21
    && c.name.startsWith("J");
});

This would further narrow it down to only California customers over 21 whose names start with “J”.

Check out Sort an Array of Objects by Property Value in TypeScript

Filter An Array of Objects on Optional Object Properties

In some cases, the objects you want to filter may have optional properties that can be undefined. You’ll need to handle this in your filter callback to avoid TypeScript compile errors.

Say our customer objects sometimes include an optional joinDate property:

const customers = [
  { id: 1, name: "John Smith", state: "CA", joinDate: "2022-04-12" },
  { id: 2, name: "Sarah Johnson", state: "NY", age: 32 },
  { id: 3, name: "Michael Lee", state: "CA", age: 19 }
]; 

To filter for customers who joined after a certain date:

const recentCustomers = customers.filter(customer => {
  return customer.joinDate !== undefined
    && new Date(customer.joinDate) > new Date("2022-01-01");
});

We first check that joinDate is not undefined before comparing the dates, so that we don’t encounter an error if joinDate is missing on some objects.

Read Filter an Array of Objects in TypeScript

Filter a Typed Array in TypeScript

One of the key benefits of using TypeScript is the type safety it provides. We can define a type or interface for our objects to get type checking and editor autocompletion:

interface Customer {
  id: number;
  name: string;
  state: string;
  age?: number; 
}

const customers: Customer[] = [
  { id: 1, name: "John Smith", state: "CA", age: 25 },
  { id: 2, name: "Sarah Johnson", state: "NY" },
  { id: 3, name: "Michael Lee", state: "CA", age: 19 }
];

When we filter a typed Customer[] array, the resulting array will also be of type Customer[]:

const caCustomers = customers.filter(c => c.state === "CA");
// caCustomers is of type Customer[]

This ensures we maintain type safety and catch any errors at compile-time.

Filter An Array of Objects on Nested Object Properties

Sometimes, you may need to filter based on the properties of nested objects. For example, each customer could have an address object containing city and zipCode:

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

const customers: Customer[] = [
  { 
    id: 1, 
    name: "John Smith",
    address: {
      city: "San Francisco",
      zipCode: "94111"
    }
  },
  {
    id: 2,
    name: "Sarah Johnson",
    address: {
      city: "New York", 
      zipCode: "10005"
    }
  },
  {
    id: 3,  
    name: "Michael Lee",
    address: {
      city: "Los Angeles",
      zipCode: "90012" 
    }
  }
];

To filter for customers in a certain city:

const sfCustomers = customers.filter(customer => {
  return customer.address.city === "San Francisco"; 
});

Or to get customers in a specific zip code range:

const bayAreaCustomers = customers.filter(customer => {
  const zip = parseInt(customer.address.zipCode);
  return zip >= 94000 && zip <= 95000;
});

We access the nested address properties to check the city and zipCode values in the filter callbacks.

Performance Considerations

When filtering large arrays, be aware that the filter() method creates a new array with the matching elements. This requires iterating through the entire original array and allocating memory for a new array, which can impact performance if done frequently on very large datasets.

In cases where performance is critical, you may want to consider other methods like for loops that allow you to process the array elements without creating a new array. But for most common web development tasks, using filter() is clean, concise, and performs more than well enough.

Conclusion

As a TypeScript developer, you should know how to filter an array of objects using multiple properties in TypeScript. In this tutorial, I have explained how to filter an array of objects on single or multiple properties, handle nested objects, or integrate with TypeScript types, etc.