A sales dashboard often receives an array of order records from an API. Before showing a “Top Sale” card, you need to identify the order with the largest total without losing its customer name, order ID, or status.
I use this pattern frequently in Node.js reporting scripts and frontend dashboards. You may need the highest invoice amount, the best-performing employee, the largest inventory count, or the most expensive product.
This guide shows several practical ways to find the maximum value in an array of objects using TypeScript, including safe handling for empty arrays, reusable generic functions, and sorting-based approaches.
What Does Maximum Value Mean?
An array is an ordered collection of values. An array of objects contains records, where each record has related properties.
For example, a sales-reporting app might receive this data:
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 1250,
status: "Paid"
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890,
status: "Paid"
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 1750,
status: "Pending"
}
];
console.log(salesOrders);Sample output:
[
{
orderId: 'ORD-1001',
customerName: 'Emily Carter',
totalAmount: 1250,
status: 'Paid'
},
{
orderId: 'ORD-1002',
customerName: 'Michael Johnson',
totalAmount: 2890,
status: 'Paid'
},
{
orderId: 'ORD-1003',
customerName: 'Olivia Williams',
totalAmount: 1750,
status: 'Pending'
}
]
Here, the maximum value is 2890, but you usually want the complete object that owns that value:
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890,
status: "Paid"
}That distinction matters. A number alone works for a chart label, but the complete record helps you build a useful dashboard card, API response, email summary, or automation result.
Before working with object arrays, it helps to understand arrays of objects in TypeScript and why a typed interface makes the code safer.
Find the Maximum Value Using reduce()
The most practical way to find the maximum value in an array of objects using TypeScript is reduce().
The reduce() method checks each item in an array and builds one final result. In this case, it compares each order with the current highest order.
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 1250,
status: "Paid"
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890,
status: "Paid"
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 1750,
status: "Pending"
}
];
const highestOrder = salesOrders.reduce((currentHighest, order) => {
return order.totalAmount > currentHighest.totalAmount
? order
: currentHighest;
});
console.log(highestOrder);
console.log(`Highest order value: $${highestOrder.totalAmount}`);Sample output:
{
orderId: 'ORD-1002',
customerName: 'Michael Johnson',
totalAmount: 2890,
status: 'Paid'
}
Highest order value: $2890You can see the output in the screenshot below.

The first object becomes currentHighest. TypeScript then compares its totalAmount with every following order.
If the current order has a larger amount, the code returns that order. Otherwise, it keeps the existing highest order. After the loop ends, highestOrder contains the full winning record.
This method does not change the original array. It only reads each object once, which makes it a strong choice for large API responses and backend processing jobs.
If you are new to this array method, see this detailed guide on the array reduce method in TypeScript.
Pro Tip: I usually use
reduce()when I need the complete object, not only the maximum number. It avoids creating another array and keeps the code fast and easy to read.
Find the Maximum Value in TypeScript Safely
The previous reduce() example works only when the array has at least one item. An empty array causes a runtime error because reduce() has no first object to use as the starting value.
In real projects, API data may be empty. A report may have no orders for the selected period. Always check the array before calling reduce().
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [];
function findHighestOrder(orders: SalesOrder[]): SalesOrder | undefined {
if (orders.length === 0) {
return undefined;
}
return orders.reduce((currentHighest, order) => {
return order.totalAmount > currentHighest.totalAmount
? order
: currentHighest;
});
}
const highestOrder = findHighestOrder(salesOrders);
if (highestOrder) {
console.log(
`Highest order: ${highestOrder.orderId} - $${highestOrder.totalAmount}`
);
} else {
console.log("No sales orders are available.");
}Sample output:
No sales orders are available.
You can see the output in the screenshot below.

The function returns SalesOrder | undefined. This union type tells TypeScript that the function may not find an object.
The if (highestOrder) check performs type narrowing. Type narrowing means TypeScript recognizes that highestOrder exists inside that block, so you can safely access highestOrder.totalAmount.
You can learn more about this pattern in TypeScript type narrowing and checking whether an array is null or empty in TypeScript.
Use Math.max() for Only the Number
Sometimes you only need the maximum numeric value. For example, a dashboard may display the highest order amount but not show the customer details.
You can extract the numeric property with map() and then pass the new number array to Math.max().
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 1250,
status: "Paid"
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890,
status: "Paid"
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 1750,
status: "Pending"
}
];
const orderAmounts: number[] = salesOrders.map((order) => order.totalAmount);
const maximumOrderAmount = Math.max(...orderAmounts);
console.log(orderAmounts);
console.log(`Maximum order amount: $${maximumOrderAmount}`);Sample output:
[ 1250, 2890, 1750 ]
Maximum order amount: $2890
You can see the output in the screenshot below.

The map() method creates a new array containing only the totalAmount values. The spread syntax (...) expands those values as separate arguments for Math.max().
This approach does not modify salesOrders, but it does create the temporary orderAmounts array. That is fine for small and medium-sized datasets.
For large datasets, I prefer reduce() because it avoids the extra array allocation. You can also explore TypeScript spread operator examples to understand why Math.max(...orderAmounts) works.
Handle an Empty Array with Math.max()
Math.max(...[]) returns negative infinity. That result rarely makes sense in an application, so handle the empty case explicitly.
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [];
const maximumOrderAmount =
salesOrders.length > 0
? Math.max(...salesOrders.map((order) => order.totalAmount))
: undefined;
console.log(maximumOrderAmount);Sample output:
undefined
Returning undefined clearly communicates that no maximum exists because the array has no records.
Find the Maximum Value Using a for…of Loop
A for...of loop is simple, fast, and easy to debug. I often use it in automation scripts where I need extra logic while comparing objects.
A function is a reusable block of code that performs a task. The function below finds the sales order with the highest amount.
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 1250,
status: "Paid"
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890,
status: "Paid"
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 1750,
status: "Pending"
}
];
function findHighestOrderWithLoop(
orders: SalesOrder[]
): SalesOrder | undefined {
let highestOrder: SalesOrder | undefined;
for (const order of orders) {
if (!highestOrder || order.totalAmount > highestOrder.totalAmount) {
highestOrder = order;
}
}
return highestOrder;
}
const highestOrder = findHighestOrderWithLoop(salesOrders);
console.log(highestOrder);Sample output:
{
orderId: 'ORD-1002',
customerName: 'Michael Johnson',
totalAmount: 2890,
status: 'Paid'
}The highestOrder variable starts as undefined. During each loop, the code stores the first order or replaces it when it finds a larger totalAmount.
This technique handles empty arrays naturally because the loop does not run. The function returns undefined instead of throwing an exception.
The for...of loop does not modify the original array. It works especially well when you need additional checks, such as ignoring cancelled orders or excluding invalid amounts. For more examples, read about for…of loops in TypeScript and TypeScript for loops with arrays.
Find the Maximum Value After Filtering
A sales dashboard may need the largest paid order, not the largest order overall. Filter the records first, then find the maximum object.
The filter() method creates a new array. It does not mutate the original array.
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 1250,
status: "Paid"
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890,
status: "Pending"
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 1750,
status: "Paid"
}
];
const paidOrders = salesOrders.filter((order) => order.status === "Paid");
const highestPaidOrder =
paidOrders.length > 0
? paidOrders.reduce((currentHighest, order) =>
order.totalAmount > currentHighest.totalAmount
? order
: currentHighest
)
: undefined;
console.log(highestPaidOrder);Sample output:
{
orderId: 'ORD-1003',
customerName: 'Olivia Williams',
totalAmount: 1750,
status: 'Paid'
}The largest order in the original array belongs to Michael, but it has a Pending status. The code filters it out before selecting the maximum value.
This is common in backend services and data-processing scripts. You may filter by region, active status, product category, date range, or permission level before finding the top record.
For additional filtering patterns, see how to filter arrays in TypeScript and how to filter an array of objects in TypeScript.
Use Sorting When You Need Rankings
Sorting works when you need more than one result. For example, a dashboard may need the top three sales orders instead of only the maximum order.
The sort() method changes the original array. This behavior is called mutation, which means directly changing an existing array or object.
Create a copy first with spread syntax if other parts of your application use the original order.
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
status: "Paid" | "Pending";
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 1250,
status: "Paid"
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890,
status: "Paid"
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 1750,
status: "Pending"
}
];
const sortedOrders = [...salesOrders].sort(
(firstOrder, secondOrder) =>
secondOrder.totalAmount - firstOrder.totalAmount
);
const highestOrder = sortedOrders[0];
const topTwoOrders = sortedOrders.slice(0, 2);
console.log("Highest order:", highestOrder);
console.log("Top two orders:", topTwoOrders);
console.log("Original order remains unchanged:", salesOrders);Sample output:
Highest order: {
orderId: 'ORD-1002',
customerName: 'Michael Johnson',
totalAmount: 2890,
status: 'Paid'
}
Top two orders: [
{
orderId: 'ORD-1002',
customerName: 'Michael Johnson',
totalAmount: 2890,
status: 'Paid'
},
{
orderId: 'ORD-1003',
customerName: 'Olivia Williams',
totalAmount: 1750,
status: 'Pending'
}
]
Original order remains unchanged: [
{
orderId: 'ORD-1001',
customerName: 'Emily Carter',
totalAmount: 1250,
status: 'Paid'
},
{
orderId: 'ORD-1002',
customerName: 'Michael Johnson',
totalAmount: 2890,
status: 'Paid'
},
{
orderId: 'ORD-1003',
customerName: 'Olivia Williams',
totalAmount: 1750,
status: 'Pending'
}
]The comparison function sorts in descending order because it subtracts the first amount from the second amount. The largest value moves to index 0.
Sorting is useful for leaderboards and reports. However, if you only need one maximum object, use reduce() or a for...of loop. They inspect each record once, while sorting does more work.
For a closer look at sorting object data, read how to sort an array of objects by property value in TypeScript.
Create a Reusable Generic Function
A generic function is a reusable function that works with many types while preserving type safety. This approach helps when your app needs to find the maximum order amount, product inventory count, employee rating, or support ticket priority.
The function below accepts any object type and a callback that returns the numeric value to compare.
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
}
interface Product {
productId: string;
productName: string;
stockCount: number;
}
function findMaxBy<T>(
items: readonly T[],
getValue: (item: T) => number
): T | undefined {
let maximumItem: T | undefined;
for (const item of items) {
if (!maximumItem || getValue(item) > getValue(maximumItem)) {
maximumItem = item;
}
}
return maximumItem;
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 1250
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 2890
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 1750
}
];
const products: Product[] = [
{
productId: "PRD-101",
productName: "Wireless Keyboard",
stockCount: 48
},
{
productId: "PRD-102",
productName: "USB-C Dock",
stockCount: 82
},
{
productId: "PRD-103",
productName: "Webcam",
stockCount: 36
}
];
const highestOrder = findMaxBy(salesOrders, (order) => order.totalAmount);
const highestStockProduct = findMaxBy(products, (product) => product.stockCount);
console.log("Highest order:", highestOrder);
console.log("Highest stock product:", highestStockProduct);Sample output:
Highest order: {
orderId: 'ORD-1002',
customerName: 'Michael Johnson',
totalAmount: 2890
}
Highest stock product: {
productId: 'PRD-102',
productName: 'USB-C Dock',
stockCount: 82
}The <T> part represents a type placeholder. TypeScript replaces T with SalesOrder when you pass sales orders and with Product when you pass products.
Notice the readonly T[] parameter. A readonly array tells TypeScript that the function should not add, remove, sort, or otherwise modify items. That makes the function safer because it only reads data.
This function does not mutate the original array. It also avoids creating temporary arrays, so it performs well for data imported from APIs, CSV files, or database queries. You can learn more in this guide to readonly arrays in TypeScript and generic object types in TypeScript.
Find the Maximum Value with Ties
Two orders may have the same maximum value. The earlier reduce() examples return the first matching object because they use the > operator.
If you need every order tied for the highest amount, first calculate the maximum number, then filter for all matching records.
interface SalesOrder {
orderId: string;
customerName: string;
totalAmount: number;
}
const salesOrders: SalesOrder[] = [
{
orderId: "ORD-1001",
customerName: "Emily Carter",
totalAmount: 2890
},
{
orderId: "ORD-1002",
customerName: "Michael Johnson",
totalAmount: 1750
},
{
orderId: "ORD-1003",
customerName: "Olivia Williams",
totalAmount: 2890
}
];
const maximumOrderAmount = Math.max(
...salesOrders.map((order) => order.totalAmount)
);
const highestOrders = salesOrders.filter(
(order) => order.totalAmount === maximumOrderAmount
);
console.log(`Maximum amount: $${maximumOrderAmount}`);
console.log("Orders with the maximum amount:", highestOrders);Sample output:
Maximum amount: $2890
Orders with the maximum amount: [
{
orderId: 'ORD-1001',
customerName: 'Emily Carter',
totalAmount: 2890
},
{
orderId: 'ORD-1003',
customerName: 'Olivia Williams',
totalAmount: 2890
}
]
This method creates a number array through map() and a filtered result array through filter(). It does not mutate salesOrders.
When you want the last matching maximum object instead, change the comparison in reduce() from > to >=. That replacement causes each tied record to replace the earlier record.
Things to Keep in Mind
- Handle empty arrays: Check
array.lengthbefore callingreduce()without an initial value. Returnundefinedwhen no maximum record exists. - Use the right return type: Return
T | undefinedfrom reusable functions so TypeScript forces callers to handle missing data safely. - Avoid sorting for one result: Use
reduce()orfor...ofwhen you only need the highest object. Sorting takes extra work and may change the array. - Remember sort() mutation:
sort()changes the original array. Use[...items].sort()when you must preserve the original order. - Avoid unnecessary copies:
map()withMath.max()creates a separate number array. For very large datasets, a loop orreduce()uses less memory. - Decide how to handle ties: Use
>to keep the first maximum object,>=to keep the last one, or filter after finding the maximum value to return all ties.
Frequently Asked Questions
How do I find the maximum value in an array of objects in TypeScript?
Use reduce() to compare a numeric property on each object and return the object with the largest value. This approach preserves the complete record, such as the order ID, customer name, and amount.
How do I get only the maximum number from an array of objects?
Use map() to create an array of numeric property values, then use Math.max(...values). Check that the original array has items first because an empty array produces negative infinity.
Does reduce() change the original array in TypeScript?
No. The reduce() method reads the array and returns one calculated result. It does not sort, remove, add, or mutate the original array.
What happens if I use reduce() on an empty array?
reduce() throws an error if you do not provide an initial value and the array is empty. Check the array length first, or write a function that returns undefined for empty input.
How do I find the maximum value in a readonly array in TypeScript?
Accept the parameter as readonly T[] and use a for...of loop or reduce(). Both techniques read the array without modifying it, so they work well with readonly data.
Should I use sort() or reduce() to find the maximum object?
Use reduce() when you need only one highest object. Use sort() when you also need a full ranking, such as the top five sales orders or a leaderboard.
Finding the maximum value in an array of objects is simple once you decide whether you need the number, one complete object, or every tied record. For most real-world TypeScript projects, I recommend reduce() or a typed for...of loop because both avoid mutation and return the object you actually need.
When the original array must stay untouched, avoid direct sorting and use a read-only comparison approach. I hope this practical guide helped you find maximum values more confidently in TypeScript.
You May Also Like
- How to initialize an array in TypeScript
- How to find an object in a TypeScript array
- How to search an array of objects by property in TypeScript
- How to get unique values from an array of objects in TypeScript
- How to update an object in an array 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.