Skip to content
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

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 opened this issue Mar 21, 2024 · 5 comments Β· Fixed by #58418
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@iclanton
Copy link
Member

iclanton commented Mar 21, 2024

πŸ”Ž 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.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Mar 21, 2024
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 5.5.0 milestone Mar 21, 2024
@DanielRosenwasser

This comment was marked as off-topic.

@jakebailey

This comment was marked as off-topic.

@iclanton

This comment was marked as off-topic.

@jakebailey

This comment was marked as off-topic.

@DanielRosenwasser DanielRosenwasser added Bug A bug in TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels Apr 26, 2024
@cheit-epic
Copy link

Our organization encountered this during our upgrade to 5.4.4. It was enough to consider reverting back to 5.2, but ultimately we ended up working around it by moving the static functions to be top-level functions instead.

@typescript-bot typescript-bot added Fix Available A PR has been opened for this issue labels May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants