10

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
  • 1
    What is unclear from the error message? You're subtracting dates, which will cause implicit type coercion, which TypeScript avoids. Commented Feb 11, 2019 at 16:06
  • The actual duplicate is TypeScript sort by date not working... Commented Feb 11, 2019 at 16:11

2 Answers 2

26

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();
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for helping, a.date and b.date are date object, but using b/a.date.getTime() was giving me an error : a.date.getTime() is not a function. But using new Date(a.date).getTime() works just fine. Wondering if the date objects are not really date object because I read them back from local storage? Not sure.
@Aragorn - If you're getting that error, they aren't Date objects. "Wondering if the date objects are not really date object because I read them back from local storage?" Yes. Web storage only stores strings.
Hey, I tried this on mine but it didn't work.. ERROR TypeError: Cannot read properties of null (reading 'getTime'
I'm trying to sort my objects by their Date field and tried your #3 solution. They are Date objects in my backend as well as my front-end
Nvm, I did the new Date(a.date).getTime() and it worked!
|
6

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
});

3 Comments

Solution 1 is just as incorrect as the OP's code, it's not clear what you're trying to achieve by assuming a.date and b.date are Date objects but then creating new Date objects...? Also, "...which means the compareFn should return a number." The OP's code does return a number. the problem is with the - operator, not the sort method callback.
Solution 1 worked for me. The date properties are date objects. However, why is that I have to create a new Date() to access getTime() function on them? Is that because of the prototype?
Not at all, it was just a leftover from me experimenting in DevTools. I cleaned up my answer. I apologize for creating confusion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.