-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Allow type narrowing of non-primitive expressions #44899
Comments
#10530 ? |
Thanks. I'm not 100% sure it's the same, there is a const-key vs dynamic-key ambiguity here:
So if these are the same, indeed we can close this, and maybe clarify that #10530 is about both cases. On the other hand, if the scope #10530 is only const-keys, I think we can keep this open (and I'll edit the description to clarify the situation) |
A problem with your example that jumps out at me immediately is that JS is so dynamic that it's hard to know, in the case of a complex expression, whether or not it will produce observable side effects. When you assign the result of the expression to a local variable, there's much more confidence that its value won't change between accesses (this can still happen in the case of closures but see #9998 for that). |
If |
Going to treat this as a duplicate of #10530 since the non-const case would not be something we'd handle until the const case was working well anyway |
Suggestion
π Search Terms
narrow type assertion expression
N.B. I looked at ~20 open requests and didn't find a duplicate, but there were many issues related to narrowing/assertions so I might have missed it
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
Currently, a variable's type is set when it is declared/initialized, but can be further refined or narrowed within a branch of the code.
Like so:
As far as I can tell, this mechanism only applies to single variables, not to more complex expressions.
I suggest we consider extending this to all expressions, with any change to any term of the expression invalidating the assumption.
π Motivating Example
Building from the previous toy exemple, consider we now assign to an object instead of a plain variable
This fails because typescript seems unable to propagate type knowledge about expressions in the same way it does with plain variables. The code can be made to work either by adding a manual cast/assertion, or by using a proxy variable / alias:
}
It would be cool if typescript could keep track of types even for expressions. Like this:
Notes:
method(this: Readonly<Class>)
) should invalidate our assumptions.π» Use Cases
This is non critical as the simple workaround is to assign the expression to a variable and narrowing will then work on that variable. The other option is to manually annotate the code with type assertions, although it's error-prone.
From a user point of view there is nothing different between a variable and an expression with regards to type, and it makes sense that they would be treated the same w.r.t. type narrowing. There are many use-cases where it would be convenient. Like when iterating over arrays or objects whose values have a broad static type, but usage indicates a more narrow type. Another simple code example below:
From a compiler point of view, I understand this is not the same thing, as there are infinite ways to build expressions, and it's harder to know when it changes (which is why I suggest invalidating the compound-narrowing as soon as any term changes as a conservative approximation)
The text was updated successfully, but these errors were encountered: