I often need this when building customer dashboards or sales-reporting tools. An API returns several records for the same customer, city, or sales region, but the dropdown or summary card should show each value only once.
TypeScript makes this job safer because you can define the object shape before you write the filtering logic. That prevents simple mistakes, such as using a property name that does not exist in your data.
Below, I will use a small customer reporting utility and show how to get unique values from an array of objects in TypeScript with complete working examples.
What Does Unique Mean in TypeScript?
A unique value appears only once in the final result. With an array of objects, you usually decide uniqueness from one property, such as city, customerId, or email.
For example, a customer dashboard may receive several orders from customers in Austin, Texas. You may want to list Austin once, even though several records use that city.
An interface defines the expected shape of an object. It helps TypeScript identify property spelling errors before you run the program. If you need a refresher, see this guide on creating an object from a TypeScript interface.
This tutorial assumes TypeScript 5+ and Node.js 18+. Create a file named unique-values.ts, then run:
npx ts-node unique-values.ts
You can also compile and run the file:
npx tsc unique-values.ts
node unique-values.js
Here is the customer data used throughout this guide:
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Olivia Davis",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 95
},
{
orderId: 1005,
customerId: 4,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
console.log(customerOrders);Sample output:
[
{
orderId: 1001,
customerId: 1,
customerName: 'Emma Johnson',
city: 'Austin',
state: 'Texas',
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: 'Daniel Miller',
city: 'Chicago',
state: 'Illinois',
total: 180
},
...
]
Get Unique Values from an Array of Objects with Set
The simplest way to get unique values from an array of objects in TypeScript is to use a Set.
A Set stores each primitive value only once. A primitive value is a basic value such as a string, number, or boolean. This makes Set ideal when you need unique city names, customer IDs, or state names.
Get unique city names
Use map() to extract city names first. Then pass that new array into Set.
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Olivia Davis",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 95
},
{
orderId: 1005,
customerId: 4,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
const uniqueCities = [...new Set(customerOrders.map((order) => order.city))];
console.log(uniqueCities);Sample output:
[ 'Austin', 'Chicago', 'Seattle' ]
I executed the above example code and added the screenshot below.

The map() method creates this intermediate array:
[ 'Austin', 'Chicago', 'Austin', 'Austin', 'Seattle' ]
Set removes repeated strings, and the spread operator converts the Set back into a regular array. This approach works well for dropdown values in a frontend web application or reporting filters in a backend API.
If you want to understand array iteration in more detail, see how to iterate over arrays in TypeScript.
Pro Tip: I use
Setfirst when I only need one primitive field, such as an ID or category. It keeps the code short, readable, and fast enough for most dashboard data.
Get unique customer IDs
The same pattern works with numbers.
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Olivia Davis",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 95
},
{
orderId: 1005,
customerId: 4,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
const uniqueCustomerIds = [...new Set(customerOrders.map((order) => order.customerId))];
console.log(uniqueCustomerIds);
console.log(`Unique customers: ${uniqueCustomerIds.length}`);Sample output:
[ 1, 2, 3, 4 ]
Unique customers: 4
I executed the above example code and added the screenshot below.

Get Unique Objects by Property with Map
Use a Map when you need the full unique objects, not just a list of property values.
A Map stores key-value pairs. In this example, the customerId becomes the key and the order object becomes the value. Since each key can appear once, Map naturally removes duplicates.
This technique is useful when a Node.js script receives duplicate API data and you need one complete record per customer.
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Olivia Davis",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 95
},
{
orderId: 1005,
customerId: 4,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
const customersById = new Map<number, CustomerOrder>(
customerOrders.map((order) => [order.customerId, order])
);
const uniqueCustomers = [...customersById.values()];
console.log(uniqueCustomers);Sample output:
[
{
orderId: 1004,
customerId: 1,
customerName: 'Emma Johnson',
city: 'Austin',
state: 'Texas',
total: 95
},
{
orderId: 1002,
customerId: 2,
customerName: 'Daniel Miller',
city: 'Chicago',
state: 'Illinois',
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: 'Olivia Davis',
city: 'Austin',
state: 'Texas',
total: 320
},
{
orderId: 1005,
customerId: 4,
customerName: 'Noah Wilson',
city: 'Seattle',
state: 'Washington',
total: 410
}
]
Notice that Emma Johnson’s second order remains in the result. Map replaces the earlier value when it finds the same customerId again.
Use this approach when you want the last object for each unique property. For more Map patterns, review how to create a Map from an array in TypeScript.
Keep the first object instead
Sometimes the first record is the one you need. For example, an API collector may process the oldest order first, and you may want to preserve that first occurrence.
Use a loop with Map.has() before inserting a value.
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Olivia Davis",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 95
},
{
orderId: 1005,
customerId: 4,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
const firstCustomerOrderById = new Map<number, CustomerOrder>();
for (const order of customerOrders) {
if (!firstCustomerOrderById.has(order.customerId)) {
firstCustomerOrderById.set(order.customerId, order);
}
}
const uniqueCustomers = [...firstCustomerOrderById.values()];
console.log(uniqueCustomers);Sample output:
[
{
orderId: 1001,
customerId: 1,
customerName: 'Emma Johnson',
city: 'Austin',
state: 'Texas',
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: 'Daniel Miller',
city: 'Chicago',
state: 'Illinois',
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: 'Olivia Davis',
city: 'Austin',
state: 'Texas',
total: 320
},
{
orderId: 1005,
customerId: 4,
customerName: 'Noah Wilson',
city: 'Seattle',
state: 'Washington',
total: 410
}
]
This version preserves order 1001 for Emma Johnson because the code ignores later records with the same customer ID.
Get Unique Values from an Array of Objects with filter()
The filter() method gives you more control when defining duplicates. It works well for smaller arrays or when you need to apply custom logic.
In this version, findIndex() finds the first object with the same customerId. filter() keeps only an object whose current index matches that first index.
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Olivia Davis",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 95
},
{
orderId: 1005,
customerId: 4,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
const uniqueCustomers = customerOrders.filter((order, index, orders) => {
return orders.findIndex(
(currentOrder) => currentOrder.customerId === order.customerId
) === index;
});
console.log(uniqueCustomers);Sample output:
[
{
orderId: 1001,
customerId: 1,
customerName: 'Emma Johnson',
city: 'Austin',
state: 'Texas',
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: 'Daniel Miller',
city: 'Chicago',
state: 'Illinois',
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: 'Olivia Davis',
city: 'Austin',
state: 'Texas',
total: 320
},
{
orderId: 1005,
customerId: 4,
customerName: 'Noah Wilson',
city: 'Seattle',
state: 'Washington',
total: 410
}
]
This keeps the first matching object, just like the previous Map.has() example. Learn more about filtering arrays in TypeScript if you want to combine uniqueness with other business rules.
I avoid this approach for very large arrays. findIndex() may scan the array repeatedly, while Set and Map usually offer a clearer and more efficient solution.
Get Unique Objects by Multiple Properties
Sometimes one field does not identify a unique record. For example, customerName alone may not be enough because two customers can share the same name.
You can create a composite key by combining two properties. Here, the customer name and city together define uniqueness.
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 4,
customerName: "Emma Johnson",
city: "Denver",
state: "Colorado",
total: 95
},
{
orderId: 1005,
customerId: 5,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
const uniqueOrdersByCustomerAndCity = [
...new Map(
customerOrders.map((order) => [
`${order.customerName.toLowerCase()}|${order.city.toLowerCase()}`,
order
])
).values()
];
console.log(uniqueOrdersByCustomerAndCity);Sample output:
[
{
orderId: 1003,
customerId: 3,
customerName: 'Emma Johnson',
city: 'Austin',
state: 'Texas',
total: 320
},
{
orderId: 1002,
customerId: 2,
customerName: 'Daniel Miller',
city: 'Chicago',
state: 'Illinois',
total: 180
},
{
orderId: 1004,
customerId: 4,
customerName: 'Emma Johnson',
city: 'Denver',
state: 'Colorado',
total: 95
},
{
orderId: 1005,
customerId: 5,
customerName: 'Noah Wilson',
city: 'Seattle',
state: 'Washington',
total: 410
}
]
The toLowerCase() calls make the comparison case-insensitive. Without them, "Austin" and "AUSTIN" would count as different values.
Use a separator that cannot appear in your source values, or serialize a structured key when your data contains unpredictable text. You can also clean API results before deduplicating them with removing undefined values from an array in TypeScript.
Create a Reusable Generic Function
A generic is a TypeScript feature that lets one function work with many data types while preserving type safety. Instead of writing separate functions for customers, products, and employees, you can build one reusable utility.
The function below accepts an array of objects and a property name. It returns unique values from that property.
interface CustomerOrder {
orderId: number;
customerId: number;
customerName: string;
city: string;
state: string;
total: number;
}
function getUniqueValues<T, K extends keyof T>(
items: T[],
key: K
): T[K][] {
return [...new Set(items.map((item) => item[key]))];
}
const customerOrders: CustomerOrder[] = [
{
orderId: 1001,
customerId: 1,
customerName: "Emma Johnson",
city: "Austin",
state: "Texas",
total: 245
},
{
orderId: 1002,
customerId: 2,
customerName: "Daniel Miller",
city: "Chicago",
state: "Illinois",
total: 180
},
{
orderId: 1003,
customerId: 3,
customerName: "Olivia Davis",
city: "Austin",
state: "Texas",
total: 320
},
{
orderId: 1004,
customerId: 4,
customerName: "Noah Wilson",
city: "Seattle",
state: "Washington",
total: 410
}
];
const uniqueCities = getUniqueValues(customerOrders, "city");
const uniqueStates = getUniqueValues(customerOrders, "state");
const uniqueCustomerIds = getUniqueValues(customerOrders, "customerId");
console.log(uniqueCities);
console.log(uniqueStates);
console.log(uniqueCustomerIds);Sample output:
[ 'Austin', 'Chicago', 'Seattle' ]
[ 'Texas', 'Illinois', 'Washington' ]
[ 1, 2, 3, 4 ]
I executed the above example code and added the screenshot below.

T represents the object type, and K extends keyof T limits the key to valid properties from that object type. That means TypeScript catches this mistake during development:
getUniqueValues(customerOrders, "country");
Because country does not exist in CustomerOrder, TypeScript reports a compile-time error. This is a strong example of why developers use TypeScript for API integrations and data-processing utilities. You can explore related patterns in this guide to generic object types in TypeScript.
Which Approach Should You Use?
Choose the method based on the result you need.
| Requirement | Best approach | Why |
|---|---|---|
| Unique strings or numbers | Set with map() | Short, clear, and efficient |
| Full unique objects, keep last item | Map | Later records replace earlier records |
| Full unique objects, keep first item | Map with has() | You control duplicate handling |
| Small dataset with custom rules | filter() with findIndex() | Flexible but less efficient for large arrays |
| Reuse logic across object types | Generic function with Set | Keeps code type-safe and maintainable |
| Unique objects from several fields | Map with a composite key | Supports multi-property comparison |
For most real-world frontend development and Node.js utilities, I start with Set for a single value and Map for complete objects.
Things to Keep in Mind
- Objects need a key:
new Set(arrayOfObjects)does not remove objects with matching properties because separate objects have different references in memory. - Choose the right property: Use a stable ID such as
customerIdor email when possible. Names and cities often repeat. - Decide first versus last: A basic
Mapkeeps the last matching object. UseMap.has()when the first record matters. - Handle missing data: Validate API data before accessing a property. Read how to check if an object is undefined in TypeScript when your source may return incomplete values.
- Avoid
any: Define an interface or type for your objects. This protects property access and improves autocomplete. See TypeScript any type for the trade-offs. - Use strict mode: Enable
"strict": truein tsconfig.json so TypeScript catches null, undefined, and property issues early.
Frequently Asked Questions
How do I remove duplicate objects from an array in TypeScript?
Use a Map keyed by a property that identifies each object, such as id or email. Convert the Map values back into an array with [...map.values()]. Use Map.has() if you want to keep the first duplicate instead of the last.
Can I use Set to remove duplicate objects in TypeScript?
Not directly when two separate objects have identical content. Set compares object references, not every property value. Extract a primitive field with map() or use a Map with a unique key.
How do I get unique values by a property in TypeScript?
Use const values = […new Set(items.map((item) => item.property))]. This extracts the property values and removes duplicates. It works well for strings, numbers, and booleans.
Does Map keep the first or last duplicate in TypeScript?
A Map keeps the last value assigned to a repeated key. Create the Map in a loop and check map.has(key) before calling map.set(key, value) to keep the first object.
How do I find unique objects using two properties in TypeScript?
Create a composite key from the two properties, such as `${item.name}|${item.city}`. Use that value as a Map key. Normalize text with toLowerCase() when your comparison should ignore letter case.
Is filter() slower than Set or Map for unique values?
It often is for large arrays when you combine filter() with findIndex(). Each item may trigger another scan of the array. Prefer Set or Map when processing large API responses or automation data.
Getting unique values from an array of objects in TypeScript becomes simple once you choose whether you need primitive values or complete objects. Start with Set for a property list and Map for object-level deduplication, then add reusable generic helpers when the same pattern appears across your project.
You May Also Like
- Get distinct values from an array in TypeScript
- Remove duplicates from an array of objects in TypeScript
- Sort an array of objects by property in TypeScript
- Find an object in an array by property in TypeScript
- Filter an array of objects in TypeScript

Bijay Kumar is an experienced Python and AI professional who enjoys helping developers learn modern technologies through practical tutorials and examples. His expertise includes Python development, Machine Learning, Artificial Intelligence, automation, and data analysis using libraries like Pandas, NumPy, TensorFlow, Matplotlib, SciPy, and Scikit-Learn. At PythonGuides.com, he shares in-depth guides designed for both beginners and experienced developers. More about us.