You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Use before declaration errors when using let statements within a switch case #19503
functiontest(value){switch(value){case1:
letfoo=10;break;case2:
foo=20;// Runtime ReferenceError: foo is not definedbreak;default:
}}test(2);tsc--targetes2015(orhigher)
Expected behavior:
This should probably produce a compile time error: Block-scoped variable 'pen' used before its declaration. on reference to foo in case 2.
Actual behavior:
The code type-checks and compiles fine, however, when running the es2015 transpiled output, you will receive a ReferenceError error at runtime. Ideally this type of error could be caught at compile time.
The current algorithm we use to detect use before def checks locations of declarations in the source file. this works in most cases, but not in cases where control flow is involved.
I've found a case that is related to this bug, but TS only catch it when strictNullChecks is true
I get a runtime error ReferenceError: Cannot access 'message' before initialization
If I understand correctly, for a var-scoped variable, maybe that's a false-positive; however, s is in a temporal dead zone in case 1, and that's a runtime error in the following case.
Activity
mhegazy commentedon Oct 26, 2017
The current algorithm we use to detect use before def checks locations of declarations in the source file. this works in most cases, but not in cases where control flow is involved.
ajafff commentedon Mar 18, 2018
In case anyone has the same issue: this bug also affects classes and enums declared in a preceding case clause.
IlanFrumer commentedon Feb 22, 2021
I've found a case that is related to this bug, but TS only catch it when strictNullChecks is true
I get a runtime error
ReferenceError: Cannot access 'message' before initializationcode on playground
detected when
"strictNullChecks": true,not detected when
"strictNullChecks": false,"strictNullChecks": falseshould only allow cases where the variable is initialized but it's value isundefinedlike in this examplemjbvz commentedon Dec 15, 2021
Real world example of this causing a bug (the commit is the fix): microsoft/vscode@7e266b2
entrywas declared in the first case but then incorrectly used in the second case even though fall through is impossibleRyanCavanaugh commentedon Dec 15, 2021
I'm trying to think of a reasonably-efficient algorithm to detect this and not coming up with many good ideas.
switchisgoto😕Update: Have something reasonable
Detect usage of block-scoped variables from earlier case blocks
RyanCavanaugh commentedon Dec 15, 2021
So the only caveat here is that we'll have unavoidable false positives:
not clear what to do about that...
DanielRosenwasser commentedon Dec 15, 2021
If I understand correctly, for a
var-scoped variable, maybe that's a false-positive; however,sis in a temporal dead zone incase 1, and that's a runtime error in the following case.RyanCavanaugh commentedon Dec 15, 2021
Daniel Rosenwasser (@DanielRosenwasser) the problem is that the code runs without error in the
0case, but we'd flag itDanielRosenwasser commentedon Dec 15, 2021
Okay, I misread. Here's one that would've been more obvious to me.