-
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
Date.getMonth could return a union of all possible values #36401
Comments
I can imagine this being a breaking change for code that does anything like this: let month = new Date().getMonth();
// next month
month = (month + 1) % 12; // error!
//~~~ <-- number not assignable to 0 | ... | 11 but I don't know how prevalent that would be in practice. Could be related to #15645 and/or #26382. |
We don't have |
I guess #28682 is currently the canonical issue for that. |
Well, then we are not able to map the types properly to the runtime behavior. Even if we had the NaN type, returning So at the moment, this may not be possible without sacrificing correctness or (if NaN would be available) usability. Related issue is numeric ranges: #29119 |
I don't think we'd take this without further feedback since it's possibly a breaking change and might interact badly with conditional types. If numeric range types ever happen, that'd be a much better fit. |
Well, we have I don't see why we can't have "regular"
That would require a type guard/assertion to go from |
If we had literally everything we could have, the language would be impossibly complex. So we need to have the things we need, not just the things that are possible. |
Well, maybe not part of TS officially. But someone could just drop the following into their project, interface DefinedDate extends Date {
getMonth () : 0|1|/*snip*/|10|11;
}
function assertDefinedDate (d : Date) : asserts d is DefinedDate {
if (isNaN(d.getTime())) {
throw new TypeError(`getTime() is NaN`);
}
}
declare const d : Date;
assertDefinedDate(d);
//0|1|...|10|11
const month : d.getMonth(); |
Search Terms
getMonth()
Date
Suggestion
According to the MDN docs,
Date.getMonth()
always returns a number between0
and11
(inclusive):Currently, the
lib.d.ts
definition states that this function returnsnumber
.So I suggest du change the definition of getMonth() from:
TypeScript/lib/lib.es5.d.ts
Lines 750 to 751 in 91ffa1c
...to something like:
Use Cases
This would be beneficial if user code contains something like
if (date.getMonth() == 12)
. The compiler can then infer that the entire if branch is dead code.Also, it serves as a quick documentation to let the user know that the return value is in fact a 0-based (not 1-based) month. The number of months in a year is also unlikely to change as well as the base (0/1) of the month index that this function returns.
Checklist
My suggestion meets these guidelines:
0 | ... | 11
is a subset ofnumber
.Remarks
This could likewise be done for
getUTCMonth()
.There are other methods like
getMinutes()
andgetSeconds()
. As they return something in the range of 0 to 60, could also be modeled using a union. However, I think that a large union like this may be considered differently.Also, there are setters for these values (like
setMonth()
). Changing the parameter of this function to take a0 | ... | 11
would actually be a breaking change. It would not reflect the runtime behaviour.setMonth(15)
would be a valid statement that will increment the year by 1 and the months by 3. So the setters should be kept as usingnumber
.If this is up for grabs, I'd take this.
The text was updated successfully, but these errors were encountered: