TypeScript Version 2.6.2
Code
example1.ts
let i = 1;
for (i = 0; i < 10; ++i) let i = 2;
example1.js
var i = 1;
for (i_1 = 0; i_1 < 10; ++i_1)
var i_1 = 2;
example2.ts
let i = 1;
for (i = 0; i < 10; ++i) { let i = 2; }
example2.js
var i = 1;
for (i = 0; i < 10; ++i) {
var i_1 = 2;
}
Expected behavior:
example1.ts and example2.ts are identical and shows us an ability to declare variables with the same name in the inner scope. In both cases counter variable for for statement should be used from the outer scope.
Actual behavior:
example1.ts fail compilation. Counter variable became global with the name of inner scope variable.
JavaScript only permits let and const declarations within a block, so example1.ts is not valid JavaScript. The compiler reports multiple errors in the example. The emitted JavaScript can be correct only if the input is correct.
https://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations
letandconst declarations define variables that are scoped to the running execution context’sLexicalEnvironment.
https://www.ecma-international.org/ecma-262/6.0/#sec-lexical-environments
A Lexical Environment consists of an
Environment Recordand a possibly null reference to an outerLexical Environment. Usually aLexical Environmentis associated with some specific syntactic structure of ECMAScript code such as aFunctionDeclaration, aBlockStatement, or aCatchclause of aTryStatementand a newLexical Environmentis created each time such code is evaluated.
https://www.ecma-international.org/ecma-262/6.0/#sec-declarative-environment-records
Each declarative
Environment Recordis associated with an ECMAScript program scope containing variable, constant, let, class, module, import, and/or function declarations.
for statement is not accessible in the scope of for statement, then it has to be mapped to inner Lexical Environment. So any variable declarations inside for statement should be mapped to the same Lexical Environment as counter does or to the inner scope.for (let i = 0; i < 10; ++i) i = 2;
console.log(i)
$ tsc test.ts
test.ts(2,13): error TS2304: Cannot find name 'i'.
You could have tested your code in a JS console before trying to convince the TS team to allow an invalid code. If you execute this in Chrome's console:
let i = 1;
for (i = 0; i < 10; ++i) let i = 2;
You'll get:
Uncaught SyntaxError: Lexical declaration cannot appear in a single-statement context
So no, TS won't allow this.
Most helpful comment
JavaScript only permits
letandconstdeclarations within a block, soexample1.tsis not valid JavaScript. The compiler reports multiple errors in the example. The emitted JavaScript can be correct only if the input is correct.