1
votes

I have this little code I borrowed from another question for sorting objects in an array by date. However, I can't figure out how to port this to TypeScript.

this.filteredTxs.sort(function(a,b): any{
        return new Date(b.date) - new Date(a.date);
});

TS Error:

ERROR in /transactions-view.component.ts(72,16): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.

/transactions-view.component.ts(72,35): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.

2
What is unclear from the error message? You're subtracting dates, which will cause implicit type coercion, which TypeScript avoids.jonrsharpe
The actual duplicate is TypeScript sort by date not working...Heretic Monkey

2 Answers

9
votes

Rather than relying on coercing Date objects to their underlying milliseconds-since-The-Epoch number values, you want to get the milliseconds-since-The-Epoch value directly and use that in the - expression.

You haven't told us what a.date and b.date are, but we can infer that they're either strings, numbers, or (at a stretch) Date instances.

Assuming a.date and b.date are strings

If a.date and b.date are strings, you can use Date.parse to parse the strings with the same rules as new Date and get the milliseconds-since-The-Epoch value directly:

return Date.parse(b.date) - Date.parse(a.date);

Note that both that and the original code in your question assume that a.date and b.date are really in an appropriate format to be parsed by the Date object.

Assuming a.date and b.date are numbers

If a.date and b.date are already milliseconds-since-The-Epoch values, use them directly:

return b.date - a.date;

Assuming a.date and b.date are Date instances

If a.date and b.date are Date instances, use getTime to get their underlying milliseconds-since-The-Epoch value:

return b.date.getTime() - a.date.getTime();
5
votes

Reason

The type signature for Array.prototype.sort is:

sort(compareFn?: (a: T, b: T) => number): this;

which means the compareFn should return a number. In your case, you're trying to subtract an object from another object which doesn't make much sense. It works only because JavaScript implicitly coerces their type for you.

Solution 1

Judging by your question, I assume filteredTxs are objects that include a date property of type Date.

Cast your Date objects to a number explicitly:

this.filteredTxs.sort(function(a,b): any{
        return (b.date.getTime() - a.date.getTime());
});

Solution 2

Use implicit casting to compare dates, but only for comparison purposes, not for subtraction.

this.filteredTxs.sort(function(a,b): any {
  .sort((a, b) => {
    if (left.date === right.date) {
      return 0;
    }

    return (left.date > right.date)
      ? 1
      : -1
});