-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
parameter initializer is bound to the wrong variable #22769
Comments
The code as emitted by the TS compiler will not work. the first example for instance will result in To generate code that would work, the compiler will have to do the initialization in a function scope other than the function itself, effectively warping the function in an IIFE. We choose a while back to not do that as it impacts the readability of the generated code, and instead we opted in adding an error instead.
I do not think this ever worked. I went back to 1.8 and the same errors are reported. |
That's only true if the target is ES3 or ES5. I'm currently targeting ES2015.
Or you could rename all function scoped identifiers (that are used somewhere in parameter initializers) that shadow declarations outside of the function. (cc @rbuckton) // foo.ts
var foo = 1;
{
let foo = 2;
}
// foo.js
var foo = 1;
{
var foo_1 = 2;
}
/**********************/
// fn.ts
let foo = 1;
(function (bar = foo) { // unexpected compiler error; works at runtime
var foo = 2;
return bar;
})();
// fn.js
var foo = 1;
(function (bar) {
if (bar === void 0) { bar = foo; }
var foo_1 = 2;
return bar; // returns 1
})();
May I ask you to reconsider this decision? I find this rather concerning as it only applies to code transpiled to ES3 and ES5. It makes using ES2015 features difficult to use because it shows errors that are technically not correct. If I didn't know much ES2015 I would think that it's not possible at all as I assume TypeScript does the correct thing. You also use this same implementation to power the JS language service which doesn't show errors by default. As a user I'm really confused when "Go to declaration" jumps to a different variable than what's used at runtime. |
In the general case, we can't know what other outside variables in scope might exist. |
We can disable the whole check if we are in ES2015 or higher. |
feel free to send us a PR for disabling the check for ES2015 or later. |
Unfortunately it's not only the error message. The whole name lookup needs to be changed to make this work as expected. |
U are right, we can change that too. |
one concern i have is that the semantics of the same code snippet would be different based on your target compilation.. |
That's why I would still prefer to rename function scoped variables that shadow variables used in a parameter initializer when transpiling to ES3 or ES5. That way you don't need to maintain and test two different implementations depending on the target.
You already make similar assumptions when transpiling lexical declarations: // no-shadow.ts
{
let foo = 1;
}
// no-shadow.js
{
var foo = 1; // assumes there is no variable `foo` in the global scope
}
/********************/
// shadow.ts
var foo = 0;
{
let foo = 1;
}
// shadow.js
var foo = 0;
{
var foo_1 = 1; // assumes there is no variable `foo_1` in the outer scope
} |
Accepting PRs to allow the ES6 scoping behavior when targeting ES6+; code should remain an error in downlevel targets |
TypeScript Version: 2.8.0-dev.20180321
Search Terms:
Code
Expected behavior:
No error on the first and second function expressions
This used to work in a previous release.
Actual behavior:
Compiler error on the first two function declarations even though the code works at runtime.
Playground Link:
Related Issues:
The text was updated successfully, but these errors were encountered: