Repository: TypeScript
Issue: `this` is incorrect for static fields and static accessors within decorators
Labels: Needs Investigation

### 🔎 Search Terms

javascript ecmascript standard decorator this static field accessor

### 🕗 Version & Regression Information

- This is an error in every version I tried (from 5.0 upward)


### ⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.2.2#code/MYewdgzgLgBAJgU2ALhgMQK5mFAluGAXhgAoBKIgPhgG8YBfAKFElhwA8jb4kHHGAZlhz4wMAO4AnAIYAHWQkkkoAC1wRUUAJ4KQAmBwo1GMGAAFlaiADpEwCsAA20iBHQgQtE6fOX1tpAoAWwRVEDhybiYfX1V-OwpoaTxgGBCwiKM+b1MLOJsEmAFcBEc4VCxEYrAEOBzYqwD7GCSUopKyirAq3Bq6+rzGwoBzUJhRqChFci6evu5JUIxJMWifQfjAlqhk3FSJ8dCppTJZhGrahaWV7JiNgq2IMafJ6fYzi7gstdy-B+bWnsWs8jm8Pr1at9+Hc-k0KNJgMAEK4QJIYAikSjJOC+gNYYVAakMciIKj0YiSaicbVvEwmIwpHIFJJrMBpI5HCRDMxwKTHAhrI4QMMSAByCAYCmuUVkRhAA

### 💻 Code

The following code incorrectly crashes when it's transformed by TypeScript and then run:

```ts
const dec: Function = () => { }
const ctx = { dec }

function wrapper(this: typeof ctx) {
  @(this.dec) class Foo {
    @(this.dec) method() { }
    @(this.dec) static method() { }

    @(this.dec) field: undefined
    @(this.dec) static field: undefined

    @(this.dec) get getter(): undefined { return }
    @(this.dec) static get getter(): undefined { return }

    @(this.dec) set setter(x: undefined) { }
    @(this.dec) static set setter(x: undefined) { }

    @(this.dec) accessor accessor: undefined
    @(this.dec) static accessor accessor: undefined
  }
}

wrapper.call(ctx)
console.log('success')
```


### 🙁 Actual behavior

The value of `this` in decorators of static fields and static accessors is inconsistent with the value of `this` in all other kinds of decorators (run [this code](https://www.typescriptlang.org/play?ts=5.2.2#code/MYewdgzgLgBAJgU2ALhgMQK5mFAluGAXhgAoBKIgPhgG8YBfAKFElhwA8jb4kHHGAZlhz4wMAO4AnAIYAHWQkkkoAC1wRUUAJ4KQAmBwo1GMGAAFlaiADpEwCsAA20iBHQgQtE6fOX1tpAoAWwRVEDhybiYfX1V-OwpoaTxgGBCwiKM+b1MLOJsEmAFcBEc4VCxEYrAEOBzYqwD7GCSUopKyirAq3Bq6+rzGwoBzUJhRqChFci6evu5JUIxJMWifQfjAlqhk3FSJ8dCppTJZhGrahaWV7JiNgq2IMafJ6fYzi7gstdy-B+bWnsWs8jm8Pr1at9+Hc-k0KNJgMAEK4QJIYAikSjJOC+gNYYVAakMciIKj0YiSaicbVvEwmIwpHIFJJrMBpI5HCRDMxwKTHAhrI4QMMSAByCAYCmuUVkRhAA) vs. [this code](https://www.typescriptlang.org/play?ts=5.2.2#code/MYewdgzgLgBAJgU2ALhgMQK5mFAluGAXhgAoBKIgPhgG8YBfAKFElhwA8jb4kHHGAZlhz4wMAO4AnAIYAHWQkkkoAC1wRUUAJ4KQAmBwo1GMGAAFlaiADpEwCsAA20iBHQgQtE6fOX1tpAoAWwRVEDhybiYfX1V-OwpoaTxgGBCwiKM+b1MLOJsEmAFcBEc4VCxEYrAEOByYAHoG2KsA+xgklKKSsoqwKtwauvq81sKAc1CYSagoRXI+gaHuSVCMSTFon1H4wI6oZNxUmenQuaUyRYRq2pW1jeyYnYK9iCm32fn2K5u4LK3cn4Xu1OkcOu8zl8foNav9+E8gW0KNJgMAEK4QJIYCi0RjJNChvUmi1diCDl0ceiIJjsaiqZiCbVvEwmIwpHIFJJrMBpI5HCRDMxwNTHAhrI4QOMSAByCAYOmuaVkRhAA)).

### 🙂 Expected behavior

I expected the value of `this` to be the same for all kinds of decorators. The value of `this` is consistent when this code is compiled with Babel.

### Additional information about the issue

For context, I'm starting to look at implementing JavaScript decorators in esbuild. I know this feature hasn't been standardized yet and is still being iterated on, but many of my users are asking for esbuild to implement it. My first step was to write a lot of tests: https://github.com/evanw/decorator-tests. That led to me discovering this bug in TypeScript.

Other bugs I noticed:

* TypeScript thinks the `@` in `() => @dec class {}` is a syntax error (demo [here](https://www.typescriptlang.org/play?ts=5.2.2#code/CYUwxgNghgTiAEEQBd6jALnlAdgTwCgAKIgSngF4A+eAAXXkigGdn4BvAX1KA)). My reading of the specification is that this should be valid as `PrimaryExpression` contains `ClassExpression` which starts with `DecoratorList opt`. Babel accepts this code.

* TypeScript generates code containing syntax errors if `await` is used in a decorator. This is allowed by the specification as far as I can tell. Here is an example: [(link)](https://www.typescriptlang.org/play?#code/IYZwngdgxgBAZgV2gFwJYHsIwO4CdgAOBAprgBQCUMA3gFAwMxSYjIwA26A5gFwwQIAtgCNSAbQC6MALwxJ9RswisYAEyGCwfAGJIoaTDJiUZAPhowAvrQUMAAmU5cAdAQQgAFmWDZgqNgAKuOiCqCDEzrjEIOjsAG7EZAAMFBQANGoaYFRQ7KAgMNro6DS2jPaO3K7uXj5+gcGh4ZHRsQlkAIypGeqCmlSCxMge6Kom1FZl5Q5O1Z7evv4wQSFhEVEx8YkATN2ZfdkwrMBosIPDo+OTU4wzVW7zdUsrTeutW2QAzHu9-fCoxHYqj4SFUxDgqAgxFUNwqswetUWDVWzQ2bUSABYflkqMdTv9AcCYKDwZDoTZytNKi4EQt6stGmsWpt2gBWbEHKhcIYwbnIZCkSggiBgiFQ1QWKLIBC4LDWSm3alzRH0l5MtEfABsHL+eNQsD5vKGAvIFGForJEomUplcopCpgdxpNTpz0ZqPe7QA7DrDuE2P6TWQAB7m0niqgTeUOp3K13I17M9FkAAcvtxyBO+qOPMDgtDxJF4ehkeuDsdStpTwT6s9iQAnOmYMAoFBojFcM3W+30Lgw2LyeXY1WkQyUW8WYkOil0vtdZn8S22yAO13lx3+5aytYyjbZTAAOQHmAAag43FoO7whBIpucw2IEG8ymwpDMpXKSk2EScz5Ar87aQgMPJI0g6NJtjST40gxNJWTSTU0i9NIUzSeswKSA8KEvbCgA). Babel prints `true` for this code while TypeScript emits invalid code. One simple hack to fix this could be for TypeScript to use `await (async () => { await ... })()` instead of `(() => { await ... })()` in this case.

* Referencing the class name within a decorator seems to return `undefined` instead of throwing a `ReferenceError`. Both TypeScript and Babel do this so I'm not sure if this is a bug with both, or if it's not a bug and the specification is outdated, or if I'm misreading the specification. Assuming this is a bug with both, it may be somewhat important to fix as people will surely try to do that (e.g. like [this](https://github.com/evanw/esbuild/issues/3326)) and a `ReferenceError` seems more clear than a value of `undefined`.