Skip to content

Scoping issue with closure in default parameters when transpiling to ES5 #17842

Closed
@jlowcs

Description

@jlowcs

TypeScript Version: 2.4.0

Code

(function foo(x, f = () => x) { var x; x++; console.log(x, f()); })(42)

Expected behavior:

console output: 43 42

(tested in Chrome, Firefox, and Edge)

Actual behavior:

console output: 43 43

Comments:

The var x; here is the important part. Without it, there is no issue (the expected result is 43 43). Also note that the code will fail to execute with let or const as the variable has already been declared.

Looking at the code TS produces...

(function foo(x, f) {
    if (f === void 0) { f = function () { return x; }; }
    var x;
    x++;
    console.log(x, f());
})(42);

...we can conclude that we can add a IIFE in order to get the expected behavior:

(function foo(x, f) {
    if (f === void 0) { f = function () { return x; }; }
    (function(x, f) {
        var x;
        x++;
        console.log(x, f());
    })(x, f);
})(42);

or

(function foo(x, f) {
    if (f === void 0) { f = (function(x) { return function () { return x; }; })(x); }
    var x;
    x++;
    console.log(x, f());
})(42);

Not sure if something can/should be done or even if it's a known issue.

The same issue can be found in BabelJS.

Also, credits goes to https://www.linkedin.com/groups/121615/121615-6302178339201306628 that made me want to test it in TypeScript.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions