-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Member-type based type guards #6062
Conversation
function narrowTypeByValueExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { | ||
assumeTrue = (expr.operatorToken.kind === SyntaxKind.EqualsEqualsEqualsToken) ? assumeTrue : !assumeTrue; | ||
let lhs = skipParenthesizedNodes(expr.left); | ||
const selectors: string[] = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document what a selector is.
I think we could discuss some issues with string literals with widening semantics. If you'd like, I'll look into what a widening approach would look like based on our earlier conversation. |
@DanielRosenwasser I've looked at it - string literal types just have to be contextually typed. Mostly because (unlike predicate types) they can appear inside arrays and object literals... and in all those cases we want them to widen away... except when we don't because there's a type annotation on the thing the literal is getting assigned to. And thus the contextual type is born - informing the type of the RHS by the type defined on the LHS side. So, my real issue: I want to run |
@weswigham I think #6196 is the answer to your first TODO 😃 |
Is this now fixed by #8010? |
Nope. type Action = { type: "REQUEST" }
| { type: "SUCCESS", data: string }
| { type: "FAILURE", error: any }
let action: Action;
if (action.type === "REQUEST"){
let inside = action; // Still `Action`
} |
I probably need to rework this PR, #8010 heavily modified the type guard code. |
a87adee
to
0e30aa1
Compare
0e30aa1
to
6636b7b
Compare
I think I've mostly reconciled the work in this PR with |
@DanielRosenwasser There's a change to the compatibility relationship test baselines (which have this kind of comparison in them) - I'm not 100% sure what the desired behavior there is, do you want to look at it? |
@weswigham Are there any plans to put this in 2.0? This would be very useful for flux based applications or any application that uses websockets or some kind of messages. |
#9163 succeeds this. Go follow that. 😄 |
This PR adds type guards of the form:
Related issues: #186, probably more.
Known issues/TODOs:
stringLiteralTypesInUnionTypes02
). It feels awkward thatgetTypeOfExpression
doesn't just return the string type and that I need to special case it, though I would like some advice on how to best do this. @DanielRosenwasser, you should know more about this, what's the best thing to do here?property lookup === expr
does). I need to rewire the other type guards to allow for nested narrowing.false
branch of aproperty lookup === expr
guard doesn't narrow yet. I'm not 100% sure on what's "safe" to remove in the false branch (probably just nested incompatible union members), though I'm pretty certain it should only do anything when the RHS type is a value literal type (ie, string literal type).if (foo["bar"]["kind"] === discriminatorType)
don't narrow right now, as I don't handleElementAccessExpression
s yet.Insights/inputs are welcome - @mhegazy mentioned he wanted me to look into these the other day, and I noticed they've been added to the roadmap for 2.0.