microsoft / microsoft/TypeScript

computed keys with private element and super call should not be hoisted when targeted to ES2022

Open
#56,754 6 comments 1 reaction 1 assignee View on GitHub

@rbuckton is already working on this.

Since Dec 13, 2023.

Bug Domain: classes Effort: Moderate
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

🔎 Search Terms

Private element, computed key, super call

🕗 Version & Regression Information
  • This is a crash
  • This changed between versions ______ and _______
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Classes
  • I was unable to test this on prior versions because _______
⏯ Playground Link

https://www.typescriptlang.org/play?target=9#code/DYUwLgBAxghgDmArgJxAEwGIHssEEpQgDORANBKkYsGANwBQUwMJEAQhAN70TRYB2RMMkRQwWZAAoAbgEouPXtHhJUmHPkKsAvBGmKAvvSP1+IAO7RmrAMIQQADzAh+aIuwW8oAoSLETJeW4lKxZ3XE8QiCEYMABLKAgAYgAzHAhdABYAJgYo6LBYhIgAbSo4EClJMHltAD4IMAA6VJxZAF08pQMu3kpqSF1YBBR0bDwCYiJJXFlaXkNjekYfLFAm4CwAc0lOCmIBiAM5oA

💻 Code
let capturedFooAccess, result;
class B {
  constructor(v) {
    capturedFooAccess = v
  }
}

new class C extends B {
  constructor() {
    class A {
      static #foo = 42;
      static [super((t) => t.#foo)];
    };
    result = capturedFooAccess(A);  
  }
}

console.log({ result });
🙁 Actual behavior

The transformed code throws "Private field '#foo' must be declared in an enclosing class" because the private key IIFE is hoisted before class A.

🙂 Expected behavior

It should print { result: 42 }

The input is already ES2022, TS could have left it as-is.

Additional information about the issue

We can dodge this issue in ES2022 target, but I haven't figured out how to deal with the decorator expression. Either we lost the #foo access or the super() is moved to the scope of the underived class A.

let capturedFooAccess, result;
class B {
  constructor(v) {
    capturedFooAccess = v
  }
}

new class C extends B {
  constructor() {
    class A {
      @(super((t) => t.#foo), v => v) #foo = 42;
    };
    result = capturedFooAccess(A);  
  }
}

console.log({ result });

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.