Prototype: Numeric Literal Types #7480
Closed
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
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,
NaN
andInfinity
are 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:
NaN
andInfinity
have their respective types only when used in type positions. They are still of typenumber
when 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.null
acts as 0 in math, andundefined
causes aNaN
, so technically, all numeric literals after a math operation should be part of a union withNaN
and 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 += 2
wherex
is 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).number
or 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.