-
Notifications
You must be signed in to change notification settings - Fork 13k
Closed
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
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.
Metadata
Metadata
Assignees
Labels
Design NotesNotes from our design meetingsNotes from our design meetings