Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript Sorting Object by Date

Tags:

typescript

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.

like image 918
Aragorn Avatar asked Dec 05 '22 10:12

Aragorn


2 Answers

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();
like image 117
T.J. Crowder Avatar answered Dec 09 '22 14:12

T.J. Crowder


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
});
like image 37
Karol Majewski Avatar answered Dec 09 '22 14:12

Karol Majewski