Prototype: Numeric Literal Types#7480
Conversation
|
thanks @weswigham. I have added this to the design meeting agenda; we have not had one in a while, so hopefully we should get to it within a couple of weeks. One thing to note, we have previously talked about how literal types fit in with enums; and that has been the main reason we held back on pushing more into literal types. I suspect this would be brought back to discussion with this proposal. |
| two = (((two ** two) - four) + (ten * two)) % three / two; | ||
|
|
||
|
|
||
| /*type True = 1; |
There was a problem hiding this comment.
Why is this commented out?
There was a problem hiding this comment.
There are tests testing guards against numeric literal types which I'll uncomment/add after #7235 is merged.
|
@ahejlsberg I'm not sure if you've seen this or not - I know you're probably already working on the same thing. At the very least I've probably got some good tests here for you. |
|
@weswigham #9407 has now been merged, so I think we can close this one. |
|
@ahejlsberg Agreed. The core feature from this PR has been implemented. |
This is a prototype for numeric literal types, in the same vein as string literal types.
All numeric syntaxes supported by JS should be supported (as far as I know) in type positions. Additionally,
NaNandInfinityare builtin to the typespace as literal subclasses of number.Also with this change:
-operator gets contextually typed if its parent is contextually typed and it applies negation to any numeric literal type after it and returns the appropriate type. Ex:-(0x08)becomes-8.+and-is valid in type positions preceeding numeric literal types. Minus makes the following number into a negative number, as you may expect. (Plus is just allowed for symmetry and to clarify +Infinity)There are tests testing guards against numeric literal types which I'll uncomment/add after #7235 is merged.
My open questions/thoughts:
NaNandInfinityhave their respective types only when used in type positions. They are still of typenumberwhen used as values for compatibility reasons.(1|3) < 2, but not assign them to one another incorrectly, it's safe to assume that this would need to use the comparable relationship reintroduced in Non-nullable types #7140. (Could also stand to add guards for numeric type unions on <=, <, >, >=) Even beyond that, if we know an enum member has the value3, should it be assignable to a numeric literal type 2? Probably not. (Though it should likely still be comparable) I've started looking down the rabbit hole of comparing enum members with numeric literal types - it requires the introduction of the concept of another literal type associated with Enum Members to carry out effectively.nullacts as 0 in math, andundefinedcauses aNaN, so technically, all numeric literals after a math operation should be part of a union withNaNand the-result-if-one-or-both-parameters-is-zero. Which seems ridiculous and makes me want to just say that advanced literal types are only available in strict null mode.x += 2wherexis already of a literal type need to be disallowed (which is only an issue since I made arithmetic operators keep around numeric literal types), OR have their type updated to reflect potential new values (either widened like Mutability widening for literal types #6554 or redefined ala Control flow based type guards #6959).numberor somesuch) as a parameter type.I probably had more questions, but I want to put this out for people to see for now. This isn't something that should be considered ready to use, but it should be a great place to start looking at what's feasible.