Closed
Description
Prefer using enum literal's own base type rather than enum's base type in comparison
- New rules on relational operators prevent this, but seems like you should be able to do it
- Agreement on expected behavior, some implementation nits to be discussed offline
Suggestion: error when using relational operators on types whose valueOf() method returns 'never' or 'void'
- Compelling use case: some objects in the Temporal API have a
valueOf
that throws (to prevent unreliable comparisons) (allegedly) - What’s the behavior when comparing things that are unions? Could a
never
return type fall out in union reduction, losing the info that comparisons should be illegal?- What type should we actually use for this?
never
implies throwing, but wouldvoid
orunknown
imply unobservability enough to merit an error? - Should we type the parameter list of
valueOf
asnever
to indicate it indicate it shouldn’t be callable, rather than checking the return type? - Is it really a huge deal if we lose some of these checks to union reduction? A best-effort seems ok here.
- What type should we actually use for this?
- We don’t currently look at
toString
orvalueOf
for coercions. Should we special-case these Temporal objects?- People will be using polyfill types / augmentations for a long time, so we couldn’t just special-case by declaration in lib files.
- How many special cases / incorrectly typed
valueOf
would we find? Seems like it could be sketchy.- Throwing doesn’t make a function return type inferred as
never
; you have to annotate it. It would returnvoid
as written in the example.
- Throwing doesn’t make a function return type inferred as
- Comparibility is pretty weird/broken already.
- Comparison isn’t actually special here—unary
+
is another example."" + foo
, unlesstoString
is implemented too. Would we need to error there too? - Any attempts to unify this are doomed to fail because of
Date
. That’s why we haven’t tried something like this earlier. - A concern is breaking comparisons of userland objects that have a
valueOf
at runtime but don’t write types for them. So, you could imagine a mode where we only prohibit comparisons wherevalueOf
is specifically marked as bad, or you could imagine a stricter mode where we only allow comparisons (between objects) where avalueOf
explicitly returns a primitive.- Not sure this proposal has value if we’re only narrowly trying to prohibit
never
-markedvalueOf
comparisons, but doing the stricter option seems super breaky.- We have RWC test data on this—mostly just
moment
and stuff like that broke - Seems like any solution should prvent you from comparing / multiplying two array literals
- We have RWC test data on this—mostly just
- Not sure this proposal has value if we’re only narrowly trying to prohibit
- It seems like this could be hard to explain to people, so maybe a syntactic marker for “this type is not coercible” would be easier to understand.
- The interplay between
valueOf
,toString
, and[Symbol.toPrimitive]
is incredibly complicated.
- The interplay between
API Requests
- Expose getStringLiteralType and getNumberLiteralType on the TypeChecker, plus remove /** @internal */ from several useful methods. #52473
getStringLiteralType
/getNumberLiteralType
- But then a few more functions as well from the type-checker.
- What are the risks?
- Reference equality bad - might not cache our types, we have several internal
any
types. - People could use the API incorrectly.
- But people want to be able to use
isAssignableTo
.
- Reference equality bad - might not cache our types, we have several internal
bigint
is missing.- Probably better to have these return the non-fresh version of the types.
- Add an API that says "give me the fresh version of each type" in the future.
- Add API option to
getCompletionsAtPosition
to expose completionsymbol
information #52560- Not a huge fan of possibly shipping cyclic data structures.
- Adding it unconditionally might break things like monaco-typescript
- Anything that currently holds references to the results will end up holding symbol objects, possibly leaking memory on symbols.