Why does Typescript when compiled convert "Let" to "var" in variables?

Asked

Viewed 353 times

4

If let variavel = "valor"; is also compatible with JavaScript, because in the compilation of Typescript, it turns to var variavel = "valor"?

Take the test right here:

function foo(){
  var x = 1;
  let y = 3;
  if (true){
    var x = 2;
    let y = 4;
    console.log(x); //Irá resultar 2.
    console.log(y); //Irá resultar 4.
  }
  console.log(x); //Irá resultar 2 porque o escopo do 'var' abrangiu toda a função foo().
  console.log(y); //Irá resultar 3 porque o escopo do 'let' abrangiu apenas o bloco, diferente da atribuição na expressão if.
}
  • 2

    It is probably because of the version of the destination Ecmascript.

  • I was thinking of leaving Babel to Tsc in Node, does this behavior happen with the latest versions of Ecmascript? 'Cause it’s become a pattern that I don’t use var in nodejs.

2 answers

7

I can not answer in a specific authoritative way, but by what I know of compilation and transpilation, makes some sense because the extra control that the let gives is the scope, that the compiler of Typescript has already guaranteed to be suitable, so there is no reason to send the JS code something for it to check again. Once he knows he is in the right scope, when the Javascript code is generated he has no more reason for the JS compiler to take care of it. It would be a redundant compilation job. I imagine compiling the var in JS is faster than compiling the let.

The JS code generated by TS does not need to be robust, does not need to be readable, is not for humans, it needs to be efficient and well done for everything to work properly, is another level of abstraction.

In fact it can be observed that it protects the variable by changing its name where it has the let:

function foo() {
    var x = 1;
    var y = 3;
    if (true) {
        var x = 2;
        var y_1 = 4;
        console.log(x);
        console.log(y_1);
    }
    console.log(x);
    console.log(y);
}

Behold functioning and transpylated in the Typescript Playground. I also put in the Github for future reference.

Also using the var ensures that it runs on older browsers that do not have the let.

  • It makes perfect sense if the context has already been secured

  • The problem I’m having is that I can’t Minify with Gulp with ES6.

  • 1

    @Ivanferrer did you change the question? Can’t, I answered what was asked. If you have another question you have to ask another question.

  • 1

    @Maniero, I didn’t change the question, I added information, your answer doesn’t answer the question of why javascript being Ecmascript 6 makes the LET variables turn into VAR, it wouldn’t even have a direct relation to typescript, I just gave an example, but the javascript itself, reuse VAR, since it can be abandoned by the same (as it is said there, since it is depreciated), would not have to reuse it in a new deprecated rereading.

6


This is because the --target (or just -t) by default will convert to ES3, very similar to ES5, but has many Apis that do not exist in it (although in this case depends on the browser) and will not use the strict mode which is something of ES5, as it is said in the documentation:

The use of ES3 as a standard is probably to try to be as backward as possible, of course this back and forth may imply some unwanted effect.

If you believe you will use Typescript only in environment that will support ES6+ then just specify to convert to the desired, remembering that let is not ES5, so if you want to use exactly how it is just adjust in the compiler:

tsc meuscript.ts -t ES6

The values supported by --target (-t) sane:

  • ES3 (standard)
  • SE5
  • ES6 or ES2015
  • ES2016
  • ES2017
  • ES2018
  • ES2019
  • ES2020
  • Esnext (these are all the latest features on https://github.com/tc39/proposals, which of course there are no guarantees to run in all environments, since this is to "convert")

So that’s the reason, the default for now is the ES3, but you have full control to adjust to what suits you.

Typescript also has many supported environments and each works in one way, so I’ll try to summarize, the tsconfig.json is the configuration file in most projects that use Typescript, with it you can configure in it how you want it to be conversion, example including some libs and conversion to ES2019:

{
  "$schema": "https://json.schemastore.org/tsconfig",

  ...
 
  "compilerOptions": {
    "lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string"],
    "module": "commonjs",
    "target": "es2019",

    ...
  }  
}

Documentation: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

Browser other questions tagged

You are not signed in. Login or sign up in order to post.