Infer string literals at comparison locations#6196
Infer string literals at comparison locations#6196DanielRosenwasser wants to merge 31 commits intomasterfrom
Conversation
…, and equality comparisons.
|
If |
|
If we do apply a contextual type to |
src/compiler/checker.ts
Outdated
There was a problem hiding this comment.
Does this even need to be a type? I mean, do you actually use the type for anything, or just check if it exists? I feel like a boolean is more appropriate.
There was a problem hiding this comment.
That actually might be a better way to go about it.
|
@RyanCavanaugh @weswigham we can discuss that on #6199. |
|
@JsonFreeman I've separated the logic out. This means we can't do both in the same pass, but ¯_(ツ)_/¯ Does anyone have any thoughts on the current approach to things? |
There was a problem hiding this comment.
Probably don't need this
src/compiler/checker.ts
Outdated
There was a problem hiding this comment.
Why not just pass current or parent here?
There was a problem hiding this comment.
I guess I assumed too much when I wrote the above comment. getContextualType expects an Expression, so we'd need to check if current is an expression using isExpression. But that function is so roundabout, I figured we'd be better off just performing the walk from literalNode again.
Additionally, you need to because we just skipped ||, where the RHS gets contextually typed by the LHS if a parent contextual type doesn't exist.
There was a problem hiding this comment.
Oh I see what you mean now about isExpression. And good point about ||.
|
I think this change is good. |
|
This change thinks you're good too Jason. ❤️ |
|
Thanks for the feedback @ahejlsberg, that really cleaned things up. One issue is that in order to truly state that an expression is an operand in a comparison location, I have to include type assertions. For the most part, this isn't a problem. You shouldn't be able to assert that the type of This might not be a huge deal, but I'd like to hear your thoughts on whether we should make an exception there. |
|
Will this include intellisense support for string literals (both for assignment and comparison)? Or should I open that as a separate issue. |
|
@DanielRosenwasser #9407 has now been merged so I think we can close this one. |
|
closing in favor of #9407 |
This PR removes ad-hoc checks for string-like types by adding new contextual types for literal types at select locations. It addresses some of the major issues brought up in #6167 by adding strictness where users are most interested.
A literal type is inferred for any string literal in a literal match location, defined as such:
switchstatement is a literal match location.caseclause is a literal match location.===,!==,==, or!=expression is a literal match location.||expression is a literal match location if the||expression itself is a literal match location.&&or,expression is a literal match location if the&&or,expression itself is a literal match location.String literals can still get string literal types through contextual typing, but a check for whether a string is in a literal match location will be apply first.
This means that the following will now error:
because types
"foo"and"bar"are not assignable to one another.