When I build sales dashboards, API data collectors, or small Node.js reporting scripts, the data rarely arrives in the order users need. A sales manager may want customers ranked by revenue, an employee directory may need names in alphabetical order, or a dashboard may need newest records first.
Sorting an array of objects in TypeScript looks simple, but small choices matter. You need to decide whether to change the original array, how to compare strings correctly, and how to keep your code type-safe.
This guide uses a small customer sales-reporting utility to show practical ways to sort an array of objects by property value in TypeScript.
Set Up the TypeScript Example
I will use TypeScript 5+ and Node.js 18+ for the command-line examples. You can use the same sorting code inside a React app, Express API, browser application, or automation script.
Create a project folder and run these commands:
npm init -y
npm install --save-dev typescript tsx @types/node
npx tsc --init
Create a file named sort-customers.ts. Then run it with:
npx tsx sort-customers.ts
An interface defines the expected shape of an object. It helps TypeScript catch mistakes before you run the code. If you need a refresher, see this guide on creating an object from an interface.
Here is the customer data used throughout this tutorial:
interface Customer {
id: number;
name: string;
city: string;
totalSales: number;
joinedOn: string;
}
const customers: Customer[] = [
{
id: 101,
name: "Emma Johnson",
city: "Austin, Texas",
totalSales: 12500,
joinedOn: "2024-08-15"
},
{
id: 102,
name: "Daniel Miller",
city: "Chicago, Illinois",
totalSales: 8700,
joinedOn: "2023-11-02"
},
{
id: 103,
name: "Olivia Davis",
city: "Seattle, Washington",
totalSales: 15800,
joinedOn: "2024-02-18"
},
{
id: 104,
name: "Michael Brown",
city: "Denver, Colorado",
totalSales: 8700,
joinedOn: "2025-01-09"
}
];
console.log(customers);Sample output:
[
{
id: 101,
name: 'Emma Johnson',
city: 'Austin, Texas',
totalSales: 12500,
joinedOn: '2024-08-15'
},
{
id: 102,
name: 'Daniel Miller',
city: 'Chicago, Illinois',
totalSales: 8700,
joinedOn: '2023-11-02'
},
{
id: 103,
name: 'Olivia Davis',
city: 'Seattle, Washington',
totalSales: 15800,
joinedOn: '2024-02-18'
},
{
id: 104,
name: 'Michael Brown',
city: 'Denver, Colorado',
totalSales: 8700,
joinedOn: '2025-01-09'
}
]
How to Sort an Array of Objects by Property Value in TypeScript
The standard approach uses JavaScript’s Array.sort() method. TypeScript adds type safety around your object properties, but the sorting behavior comes from JavaScript.
The sort() method accepts a comparison function. That function receives two objects:
- Return a negative number when the first item should appear first.
- Return a positive number when the second item should appear first.
- Return
0when both values should keep the same relative position.
For numeric properties, subtraction gives you exactly what the comparison function needs.
Sort Objects by a Number Property
Use ascending order when you want the smallest numeric value first. In a sales report, this might help you find customers who need attention.
interface Customer {
id: number;
name: string;
city: string;
totalSales: number;
joinedOn: string;
}
const customers: Customer[] = [
{
id: 101,
name: "Emma Johnson",
city: "Austin, Texas",
totalSales: 12500,
joinedOn: "2024-08-15"
},
{
id: 102,
name: "Daniel Miller",
city: "Chicago, Illinois",
totalSales: 8700,
joinedOn: "2023-11-02"
},
{
id: 103,
name: "Olivia Davis",
city: "Seattle, Washington",
totalSales: 15800,
joinedOn: "2024-02-18"
},
{
id: 104,
name: "Michael Brown",
city: "Denver, Colorado",
totalSales: 8700,
joinedOn: "2025-01-09"
}
];
const customersByLowestSales = [...customers].sort(
(firstCustomer, secondCustomer) =>
firstCustomer.totalSales - secondCustomer.totalSales
);
console.log(
customersByLowestSales.map(
(customer) => `${customer.name}: $${customer.totalSales}`
)
);Sample output:
[
'Daniel Miller: $8700',
'Michael Brown: $8700',
'Emma Johnson: $12500',
'Olivia Davis: $15800'
]
You can refer to the screenshot below to see the output.

The spread operator (...customers) creates a shallow copy before sorting. This matters because sort() changes the original array. Read more about the TypeScript spread operator if you often copy or combine arrays.
Sort an Array of Objects by Property Value Descending
For leaderboards and sales dashboards, descending order usually makes more sense. You want the highest total first.
Reverse the subtraction order:
secondCustomer.totalSales - firstCustomer.totalSales
Here is the full TypeScript example:
interface Customer {
id: number;
name: string;
city: string;
totalSales: number;
joinedOn: string;
}
const customers: Customer[] = [
{
id: 101,
name: "Emma Johnson",
city: "Austin, Texas",
totalSales: 12500,
joinedOn: "2024-08-15"
},
{
id: 102,
name: "Daniel Miller",
city: "Chicago, Illinois",
totalSales: 8700,
joinedOn: "2023-11-02"
},
{
id: 103,
name: "Olivia Davis",
city: "Seattle, Washington",
totalSales: 15800,
joinedOn: "2024-02-18"
},
{
id: 104,
name: "Michael Brown",
city: "Denver, Colorado",
totalSales: 8700,
joinedOn: "2025-01-09"
}
];
const customersByHighestSales = [...customers].sort(
(firstCustomer, secondCustomer) =>
secondCustomer.totalSales - firstCustomer.totalSales
);
console.log(
customersByHighestSales.map(
(customer) => `${customer.name}: $${customer.totalSales}`
)
);Sample output:
[
'Olivia Davis: $15800',
'Emma Johnson: $12500',
'Daniel Miller: $8700',
'Michael Brown: $8700'
]
You can refer to the screenshot below to see the output.

I use this pattern often in customer dashboards because it stays readable. The comparison function clearly says, “Put the larger sales value before the smaller one.”
Pro Tip: I always copy the array before sorting when the source data may feed another screen, calculation, or API response. A hidden mutation from
sort()causes confusing bugs later.
Sort Objects by a String Property
You should not sort names with subtraction. For strings, use localeCompare().
localeCompare() compares text values in a language-aware way. It returns a negative, positive, or zero value that works directly with sort().
Sort Customer Names Alphabetically
interface Customer {
id: number;
name: string;
city: string;
totalSales: number;
joinedOn: string;
}
const customers: Customer[] = [
{
id: 101,
name: "Emma Johnson",
city: "Austin, Texas",
totalSales: 12500,
joinedOn: "2024-08-15"
},
{
id: 102,
name: "Daniel Miller",
city: "Chicago, Illinois",
totalSales: 8700,
joinedOn: "2023-11-02"
},
{
id: 103,
name: "Olivia Davis",
city: "Seattle, Washington",
totalSales: 15800,
joinedOn: "2024-02-18"
},
{
id: 104,
name: "Michael Brown",
city: "Denver, Colorado",
totalSales: 8700,
joinedOn: "2025-01-09"
}
];
const customersByName = [...customers].sort((firstCustomer, secondCustomer) =>
firstCustomer.name.localeCompare(secondCustomer.name)
);
console.log(customersByName.map((customer) => customer.name));Sample output:
[
'Daniel Miller',
'Emma Johnson',
'Michael Brown',
'Olivia Davis'
]
You can refer to the screenshot below to see the output.

This approach works well for names, cities, product categories, status values, and other text fields. You can also sort cities if your user needs a location-based customer list.
const customersByCity = [...customers].sort((firstCustomer, secondCustomer) =>
firstCustomer.city.localeCompare(secondCustomer.city)
);
console.log(customersByCity.map((customer) => customer.city));
Sample output:
[
'Austin, Texas',
'Chicago, Illinois',
'Denver, Colorado',
'Seattle, Washington'
]
If your data may include upper- and lowercase values, normalize both strings before comparing:
firstCustomer.name.toLowerCase().localeCompare(
secondCustomer.name.toLowerCase()
);
Sort an Array of Objects by Date Property
APIs commonly return dates as strings. If your date strings use ISO format (YYYY-MM-DD), you can convert them to Date objects and compare their timestamps.
A timestamp is the numeric time value returned by getTime().
Sort Customers by Newest Join Date
interface Customer {
id: number;
name: string;
city: string;
totalSales: number;
joinedOn: string;
}
const customers: Customer[] = [
{
id: 101,
name: "Emma Johnson",
city: "Austin, Texas",
totalSales: 12500,
joinedOn: "2024-08-15"
},
{
id: 102,
name: "Daniel Miller",
city: "Chicago, Illinois",
totalSales: 8700,
joinedOn: "2023-11-02"
},
{
id: 103,
name: "Olivia Davis",
city: "Seattle, Washington",
totalSales: 15800,
joinedOn: "2024-02-18"
},
{
id: 104,
name: "Michael Brown",
city: "Denver, Colorado",
totalSales: 8700,
joinedOn: "2025-01-09"
}
];
const customersByNewestJoinDate = [...customers].sort(
(firstCustomer, secondCustomer) =>
new Date(secondCustomer.joinedOn).getTime() -
new Date(firstCustomer.joinedOn).getTime()
);
console.log(
customersByNewestJoinDate.map(
(customer) => `${customer.name}: ${customer.joinedOn}`
)
);Sample output:
[
'Michael Brown: 2025-01-09',
'Emma Johnson: 2024-08-15',
'Olivia Davis: 2024-02-18',
'Daniel Miller: 2023-11-02'
]
For date-heavy projects, validate incoming dates before sorting. Invalid data from an API can produce NaN, which makes the sort result unreliable. This guide on checking for invalid dates in TypeScript can help you build a safer validation step.
Sort by Multiple Object Properties
Real business data often contains ties. In our customer list, Daniel Miller and Michael Brown both have total sales of $8,700.
You can use a second property as a tie-breaker. First sort by total sales, then sort matching values by name.
interface Customer {
id: number;
name: string;
city: string;
totalSales: number;
joinedOn: string;
}
const customers: Customer[] = [
{
id: 101,
name: "Emma Johnson",
city: "Austin, Texas",
totalSales: 12500,
joinedOn: "2024-08-15"
},
{
id: 102,
name: "Daniel Miller",
city: "Chicago, Illinois",
totalSales: 8700,
joinedOn: "2023-11-02"
},
{
id: 103,
name: "Olivia Davis",
city: "Seattle, Washington",
totalSales: 15800,
joinedOn: "2024-02-18"
},
{
id: 104,
name: "Michael Brown",
city: "Denver, Colorado",
totalSales: 8700,
joinedOn: "2025-01-09"
}
];
const customersBySalesThenName = [...customers].sort(
(firstCustomer, secondCustomer) => {
const salesDifference = secondCustomer.totalSales - firstCustomer.totalSales;
if (salesDifference !== 0) {
return salesDifference;
}
return firstCustomer.name.localeCompare(secondCustomer.name);
}
);
console.log(
customersBySalesThenName.map(
(customer) => `${customer.name}: $${customer.totalSales}`
)
);Sample output:
[
'Olivia Davis: $15800',
'Emma Johnson: $12500',
'Daniel Miller: $8700',
'Michael Brown: $8700'
]
This pattern makes tables and reports predictable. Users appreciate stable, logical ordering when they export data or compare records.
Create a Reusable Type-Safe Sort Function
When I sort different datasets in the same application, I avoid writing one-off comparison functions everywhere. A reusable generic function keeps the code consistent.
A generic is a TypeScript feature that lets one function work with many object shapes while preserving type safety. The function below accepts an array, the property to sort, and the direction.
type SortDirection = "asc" | "desc";
function sortByProperty<T extends Record<string, string | number>>(
items: readonly T[],
property: keyof T,
direction: SortDirection = "asc"
): T[] {
const multiplier = direction === "asc" ? 1 : -1;
return [...items].sort((firstItem, secondItem) => {
const firstValue = firstItem[property];
const secondValue = secondItem[property];
if (typeof firstValue === "number" && typeof secondValue === "number") {
return (firstValue - secondValue) * multiplier;
}
return (
String(firstValue).localeCompare(String(secondValue), undefined, {
sensitivity: "base"
}) * multiplier
);
});
}
interface Customer {
id: number;
name: string;
city: string;
totalSales: number;
joinedOn: string;
}
const customers: Customer[] = [
{
id: 101,
name: "Emma Johnson",
city: "Austin, Texas",
totalSales: 12500,
joinedOn: "2024-08-15"
},
{
id: 102,
name: "Daniel Miller",
city: "Chicago, Illinois",
totalSales: 8700,
joinedOn: "2023-11-02"
},
{
id: 103,
name: "Olivia Davis",
city: "Seattle, Washington",
totalSales: 15800,
joinedOn: "2024-02-18"
},
{
id: 104,
name: "Michael Brown",
city: "Denver, Colorado",
totalSales: 8700,
joinedOn: "2025-01-09"
}
];
const customersBySales = sortByProperty(customers, "totalSales", "desc");
const customersByName = sortByProperty(customers, "name", "asc");
console.log(
"By sales:",
customersBySales.map((customer) => `${customer.name}: $${customer.totalSales}`)
);
console.log(
"By name:",
customersByName.map((customer) => customer.name)
);
Sample output:
By sales: [
'Olivia Davis: $15800',
'Emma Johnson: $12500',
'Daniel Miller: $8700',
'Michael Brown: $8700'
]
By name: [
'Daniel Miller',
'Emma Johnson',
'Michael Brown',
'Olivia Davis'
]
Notice that TypeScript only lets you pass valid customer properties such as "name", "city", or "totalSales". Passing "emailAddress" causes a compile-time error because that property does not exist in the Customer interface.
For larger applications, this kind of type safety prevents many UI sorting bugs. You can also explore advanced object type safety in TypeScript when working with dynamic object properties.
Things to Keep in Mind
- Avoid mutating source data:
sort()changes the original array, so use[...items]ortoSorted()when other code needs the original order. - Use correct comparators: Subtract numeric values, use
localeCompare()for strings, and compare timestamps for dates. - Handle missing values: API data may contain
nullorundefined; decide whether incomplete records should appear first or last before sorting. - Keep strict mode enabled: Configure
"strict": truein tsconfig.json so TypeScript alerts you about unsafe property access and uncertain values. - Validate API data: Check property types before sorting response data from an external API, especially when fields may arrive as strings instead of numbers.
- Use a tie-breaker: Sort by a second property when the main property contains duplicate values, such as equal revenue totals.
Frequently Asked Questions
How do I sort an array of objects by property value in TypeScript?
Call sort() with a comparison function that compares the chosen property. Use a.price - b.price for numbers and a.name.localeCompare(b.name) for strings. Copy the array first if you need to preserve its original order.
Does TypeScript sort() modify the original array?
Yes. The sort() method changes the same array in place. Use [...array].sort() to create and sort a copy instead.
How do I sort an array of objects in descending order?
Reverse the comparison. For a numeric property, use b.totalSales - a.totalSales; for a string property, use b.name.localeCompare(a.name).
Can I sort TypeScript objects by two properties?
Yes. Compare the primary property first, then compare a secondary property only when the first comparison returns 0. This approach gives tied records a reliable and readable order.
How do I sort object arrays with undefined values?
Handle missing values before the normal comparison. For example, return 1 when the first value is undefined to move it to the bottom, and return -1 when the second value is undefined.
Is localeCompare() better than < for sorting strings?
Usually, yes. localeCompare() provides more reliable alphabetical ordering and offers options for case sensitivity. It works especially well for customer names, cities, and labels shown in a web application.
You can now sort an array of objects by number, text, date, and multiple property values in TypeScript. Start with a simple typed comparison function, preserve the original array when needed, and move to a reusable generic helper as your project grows. I hope you found this article helpful.
You May Also Like
- Sort arrays in TypeScript
- Work with arrays of objects in TypeScript
- Sort an array by date in TypeScript
- Filter an array of objects in TypeScript
- Find an object in an array by property

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.