iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To keep one object per property value, track values in a Set while filtering the array. This keeps the first matching object and preserves input order. If the last matching object should win instead, use a Map and overwrite each key as you iterate.
Keep the first object for each property value
Use a generic helper that accepts an array and a key belonging to its object type:
function uniqueBy<T, K extends keyof T>(items: T[], key: K): T[] {
const seen = new Set<T[K]>();
return items.filter((item) => {
const value = item[key];
if (seen.has(value)) return false;
seen.add(value);
return true;
});
}
For example, given users as an array of objects with an id property, call uniqueBy(users, "id"). The type parameter K extends keyof T restricts the key argument to a property on the array’s object type, and T[K] makes the set hold values of that property’s type. This is a compile-time type relationship, not a change to JavaScript’s runtime behavior; see TypeScript’s Object Types handbook.
Free tools Windows power users keep installed
One-click scans. No signup required.
filter visits items in input order. The first time it encounters a value, the helper records it and keeps the object; later objects with an equal key are rejected. The result is a new array containing the original object references. Neither the input array nor its objects are mutated.
#1 Best Overall
Keep the last object for each property value
When later records should replace earlier ones, store each object in a Map keyed by the chosen property:
function uniqueByLast<T, K extends keyof T>(items: T[], key: K): T[] {
const byKey = new Map<T[K], T>();
for (const item of items) byKey.set(item[key], item);
return [...byKey.values()];
}
Setting a key that is already in the map replaces its value, so the returned array contains the last object encountered for each key. The map retains the key’s original insertion position: output order follows the first appearance of each distinct key, not the position of its winning object. See MDN’s Map reference for its key and iteration behavior.
Rank #2
- TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
- TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
Choose the approach based on the result you need
| Approach | What survives | Output and order |
|---|---|---|
filter with a Set |
First object for each key | Flat array in original input order |
Map overwrite |
Last object for each key | Flat array ordered by each key’s first insertion |
Map.groupBy |
All objects in each key group | A map of arrays, not a flat array of representatives |
Use the first two when you need one representative per key. Use Map.groupBy when you need all records grouped together and the runtime supports it. TypeScript 5.4 added declarations for Map.groupBy and Object.groupBy; check your TypeScript lib configuration and JavaScript runtime support, because declarations do not add the API to an older runtime. See the TypeScript 5.4 release notes.
Recommended Free Tools
Understand what counts as the same key
A Set of whole objects does not deduplicate separate objects merely because their fields are equal. Objects are compared by reference identity, so two separately created objects with the same property values are distinct set entries. Select the property that defines uniqueness and store that value instead. MDN explains these behaviors in its Set reference and keyed collections guide.
For primitive keys, Map and Set use SameValueZero equality: NaN matches NaN, and positive and negative zero count as equal. For object-valued keys, equality is by identity, not by matching fields.
Handle composite and irregular keys deliberately
Objects with more than one identifying field
For uniqueness based on multiple properties, define a stable composite key. Do not create a fresh object or tuple for each record and use it as a map key: each new reference is distinct, even when its contents match another key. A string encoding can work for primitive fields, but naive delimiter concatenation can collide when values contain that delimiter. Choose an unambiguous encoding or use nested maps when fields have mixed types.
Missing, null, or case-insensitive values
If the chosen property may be missing or null, decide whether such records belong to one shared duplicate group, should be excluded, or need separate treatment. If matching should ignore letter case, normalize the key before checking or storing it.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Object-valued properties
If a property contains an object and you want structural rather than reference-based matching, define what structural equality means for your data and build a deliberate key. JSON serialization is not a universally safe shortcut: property ordering, unsupported values, and differences in semantic meaning can affect whether serialized strings are appropriate keys.
Best Value
Performance expectations
MDN specifies that Map and Set access must be, on average, sublinear in collection size; this does not promise a particular implementation or exact O(1) runtime. Avoid claiming a precise speed or complexity guarantee for a specific workload without measuring it in the relevant JavaScript runtime and with representative data.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

