-
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
No error when an arrow function uses a variable from an unreachable branch #56827
Comments
(Probably) another duplicate of #9998. |
I don't think so. This is not entirely about control flow analysis; the In particular, I'm not complaining about locals used before they're declared (eg, if you move |
Itβs not actually out of scope, just in the temporal deadzone (the identifier itself is hoisted), which is the purview of CFA. in other words itβs only βout of scopeβ because you return early and the variable never leaves TDZ. |
@fatcerebus - I don't know whether you are talking about JS or TS hoisting of JS hoists TS CFA treats |
@craigphicks #9998 still applies; the same design limitations that cause the problems described there are at play here.
This is a common misconception. const foo = "bar";
{
// console.log(foo); // nope, runtime error
const foo = "qux";
console.log(foo); // ok, "qux"
} and the below code does work precisely because the variable is hoisted: setTimeout(() => console.log(foo), 0); // ok, "bar"
const foo = "bar"; |
Your case 1.1 does show something.
The The second case works only because |
This is just a roundabout way to say the inner const is hoisted to the top of its scope. Semantically, the hoisting is almost the same as for |
This is a duplicate of #11498. It's sometimes valid and idiomatic to write this code, but we don't know if it's safe or not unless we know the semantics of the receiver of the callback. It's not practical to always error on this, so the only thing we can do is never error. |
Thanks @RyanCavanaugh, I knew duping to #9998 was sketchy and I always forget about #11498 π |
Not in this case; because the |
IOW, if a variable's declaration is never reachable from a nested function's definition, you should emit an error when using the variable from inside the nested function. |
I don't think the control-flow analyzer is that sophisticated; the |
It's complicated, but there's help from MDN:
Could we say TDZ correlates with lexical scope? |
No, because it doesnβt: switch ("foo" as string) {
case "bar":
const foo = 0;
case "foo":
console.log(foo); // runtime error (TDZ)
}
|
"correlates with" does not mean "equates to". So the counter example is not proof that "correlates with" is not an accurate description. Correlates only means "is not independent of". |
For what it is worth if the branch is always true:
|
This isn't a useful hypothetical. If it "can never be valid" then no one would write the |
@RyanCavanaugh It is true in this case that, if |
if the CFA chooses to recognize the branch condition as always true. |
No, thatβs irrelevant - even if the branch condition is only sometimes true, calling |
That's seems true. However, because of #11498, for the general case, const declarations are hoisted. So #11489 is the crux here. By hoisting, the CFA can safely assume reference by (async) functions at the top scope and any subscopes, early returns or no. To allow for this case, it would have to know otherwise. |
Yes, Iβm fully aware - I was specifically arguing against Ryanβs assertion that this code could ever be valid as written (it canβt). |
Just to issue clarity, the above particular case produces a runtime error, as expected.
While this done doesn't:
Any program calling |
This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
π Search Terms
variable used before declaration function
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play?ts=5.3.2#code/BTCUAIF4D5wbwFDnASwGbmAWQIYBcALAOhwCMBnYARgkjvBviWXACcBTARwFd3y8AggDsUAW3woA9kIBirHKPYhasAMbTykgDbsiWyQHNgaSZNCgA3M2Qc83VkKvIAvs3VD+4E5KjgATE7g7po6eobGppYIzqBgVkA
π» Code
π Actual behavior
Fails at runtime with
π Expected behavior
The same error, but at compile time
Additional information about the issue
If you replace
requestAnimationFrame()
with an IIFE (``), it correctThe text was updated successfully, but these errors were encountered: