Skip to content

A shadowed variable is generated in a an async function with a default parameter declared as a static property of a class when targeting ES5.Β #57897

Closed
@iclanton

Description

@iclanton

πŸ”Ž Search Terms

"shadowed", "shadowed variable", "generator"

πŸ•— Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play?target=1&ts=5.4.3#code/MYGwhgzhAEAa0G8BQ1oAcCuAjEBLY0EALmEftGNALwUQCeAdgQBQQD2AtgKYBqYATgC5oWNmxBcwDatCL8MXAJTUAfIhSpo-LkQz9pYAO5hcROADoszRQG4NAXzsbMOcsVLksMyIxbKqasiaWjp60gBEAOIA8tEAIuF2qI5I9khIACZcoAJc0DlQ6PxswFyFQYQkZARcAB6mzMBsWcIMGBxYXPyKrVwAbl12aUiw5mDWGuZEABZcDI1sDOwS5iBsAOaKk8CkwNPM1qrqwU1L4lzmXcX8zOEAQgCCCbYaqGjFpVCX9UTMAIwvZIvIA

πŸ’» Code

class X {
  public static a = async (someVar: boolean = true) => {
    return await X.b();
  };

  public static b = async () => {
    return "GOOD";
  };
}

declare class process {
  static exit(code: number): never;
}

X.a()
  .then(console.log)
  .catch(() => {
    console.error("BAD");
    process.exit(1);
  });

πŸ™ Actual behavior

Between TS v5.4.2 and TS v5.3.3, the generated code from the above code sample changes to shadow the _a variable in the outer closure. See diff below:

var X = /** @class */ (function () {
    function X() {
    }
    var _a;
    _a = X;
-    X.a = function (someVar) {
-        if (someVar === void 0) { someVar = true; }
-        return __awaiter(_a, void 0, void 0, function () {
-            return __generator(_a, function (_b) {
-                switch (_b.label) {
+    X.a = function () {
+        var args_1 = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            args_1[_i] = arguments[_i];
+        }
+        return __awaiter(_a, __spreadArray([], args_1, true), void 0, function (someVar) {
+            if (someVar === void 0) { someVar = true; }
+            return __generator(_a, function (_a) {
+                switch (_a.label) {
                     case 0: return [4 /*yield*/, _a.b()];
-                    case 1: return [2 /*return*/, _b.sent()];
+                    case 1: return [2 /*return*/, _a.sent()];
                }
            });
        });
    };
    X.b = function () { return __awaiter(_a, void 0, void 0, function () {
        return __generator(_a, function (_b) {
            return [2 /*return*/, "GOOD"];
        });
    }); };
    return X;
}());
X.a()
    .then(console.log)
    .catch(function () {
    console.error("BAD");
    process.exit(1);
});

Note that helpers have been omitted from this code sample.

Notice that in the context of the function, the class/function X is assigned to a variable _a in the "ambient" context of the class. In TS v5.3.3, the async state machine's state variable is declared as _b, but in TS v.5.4.2 is appears as if the context is lost when the state machine is generated, so the state is declared as _a, shadowing the earlier-declared _a.

πŸ™‚ Expected behavior

Expected that the async state machine's state variable does not shadow another variable.

Additional information about the issue

No response

This issue was found by @ipip2005.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions