Typescript: Variable declaration using "let" keyword fails in "for" statements

Created on 4 Dec 2017  Â·  3Comments  Â·  Source: microsoft/TypeScript




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.

Working as Intended

Most helpful comment

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.

All 3 comments

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

let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment.

https://www.ecma-international.org/ecma-262/6.0/#sec-lexical-environments

A Lexical Environment consists of an Environment Record and a possibly null reference to an outer Lexical Environment. Usually a Lexical Environment is associated with some specific syntactic structure of ECMAScript code such as a FunctionDeclaration, a BlockStatement, or a Catch clause of a TryStatement and a new Lexical Environment is created each time such code is evaluated.

https://www.ecma-international.org/ecma-262/6.0/#sec-declarative-environment-records

Each declarative Environment Record is associated with an ECMAScript program scope containing variable, constant, let, class, module, import, and/or function declarations.

  • So what?
  • If counter for 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.

Was this page helpful?
0 / 5 - 0 ratings