-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot perform arithmetic on Dates #9356
Comments
Duplicate of #8260 |
It's not being ignored, it's omitted by design. Implicit conversions are the source of bugs. If all valid ES was valid TS there would not be much point to TS. If one really wants to subtract dates then that issue shows how to convince the compiler to allow it. |
Is there a design document, or something else that talks about this idea? Are there other parts of the ES spec that TS chose not to implement? Implicits are understandably notorious for causing bugs in dynamically typed languages (as are almost all language features :)), but they are a core part of many statically typed languages (C#, Scala, Haskell), so it seems silly to omit them. Especially if you want to work with JS code in the wild, which uses toString, valueOf, and toJSON implicitly all the time. |
@bcherny the "design document" is TypeScript Design Goals which says:
which I think applies the case of |
How do you plan on interoperating with existing, JSDoc'd code if the compiler doesn't understand implicits? |
Consider new Date() - new Date() // 0 That output is reasonable var d = new Date();
d.setHours(3);
d - new Date() // -43218751
d + new Date() // "Sat Jun 25 2016 03:51:22 GMT-0400 (Eastern Daylight Time)Sat Jun 25 2016 17:54:37 GMT-0400 (Eastern Daylight Time)" This is really weird behavior and I don't think it should be encouraged. |
@aluanhaddad Encouraging/discouraging behavior should be left to tslint, I think. TypeScript should first and foremost understand the rules of the ES specs, and help TS and existing JS code scale given those rules. If there's a whole bunch of existing JS code that TS is unable to infer and flow types for, that makes TS less valuable to a lot of developers! |
@bcherny in principle I absolutely agree with that statement. I oppose proposals that would fundamentally change the semantics of JavaScript and proposals which did not map intuitively to JavaScript. |
@bcherny nearly everything TypeScript flags as an error has some valid runtime interpretation. If you want to use This is really a dupe of #2361 because |
@RyanCavanaugh thank you for calling date insane, that's really what I was trying to say, only you did so much more concisely ❤️ |
@aluanhaddad I agree that JS implicits can lead to subtle bugs! @RyanCavanaugh There's an argument to be made that if someone writes: let a: number = [ ] * { } The TS compiler should be OK with it, since this is valid JS, and TS is a superset of JS. If someone then tries to do something with Anyway, to wrap up it sound like what you guys are saying is "TS is ok with some implicits (eg. conversion to boolean via logical operators like |
Can this be reopened please? Date arithmetic is a valid correct and reasonable operation completely within JS day-to-day established good practices. Without it things like max/min date, average date, closest date are a pain to write. Are there practical use cases where preventing date arithmetic would highlight a genuine error? The examples above are extremely artificial. |
@mihailik It seems like const dates = [new Date(), new Date(), new Date(), new Date(), new Date()];
const average = dates.reduce((total, date) => total + date, 0) / dates.length; This results in |
Date arithmetic fails the most basic of mathematical identities, e.g. |
Artificial though it is, I guess what you're really trying to say is that in past you've been burnt by dates, and prefer to skip the whole business. I better stop insisting. |
I've started working on a solution to this over in #2361 |
Potential solution could just be allowing a cast to number or string... let a: number = date1 - date2; But allow let a: number = <number>date1 - <number>date2; And allow let a: string = <string>date1 + <number>date2; But obviously disallow let a: number = date1 + <number>date2; Ie disallow the operation by changing what the return type of the arithmetic is considered to be, but allow casting dates in date arithmetic so that the return type can be perceived as string or as number. |
JS will implicitly convert these to numbers via
valueOf
, so explicit conversion is not necessary.The text was updated successfully, but these errors were encountered: