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

ClassFieldDecoratorContext has addInitializer method which is not part of the spec. #57096

Closed
phiresky opened this issue Jan 19, 2024 · 4 comments
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@phiresky
Copy link

πŸ”Ž Search Terms

ClassFieldDecoratorContext, addInitializer, decorators, undefined

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried (5.04 up to nightly), and I reviewed the FAQ for entries about decorators

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.4.0-dev.20240119#code/GYVwdgxgLglg9mABAIwIYCcAUB9AXI1MATwBpFoAPfAYQBtUBnBgMRgFNaATAETYjnSooA6gihsKUAJSIA3gChE5BAzi02AOlpwA5pgBEDABZwQXFG0ThObYDDBtO+spQ2pOnAJJgYsVLRgALzZ0KQBueQBfeQh6JkRmODg5RUQAATR0FFRAxABeRABGKKA

πŸ’» Code

function bar(_: any, ctx: ClassFieldDecoratorContext) {
  console.log("should be undefined", ctx.addInitializer);
}
class Foo {
  @bar baz = 1
}

πŸ™ Actual behavior

addInitializer is a function and ClassFieldDecoratorContext defines it as such

πŸ™‚ Expected behavior

should be undefined undefined + a typescript compile error because it's wrong code

Additional information about the issue

This is problematic because babel apparently follows whatever typescript does so it does work there, but swc follows the spec so code breaks there. For example, mobx works when compiling with tsc but breaks with swc: mobxjs/mobx#3817

Here's excerpts from the spec:

https://github.com/tc39/proposal-decorators

type ClassFieldDecorator = (value: undefined, context: {
  kind: "field";
 name: string | symbol;
 access: { get(): unknown, set(value: unknown): void };
 static: boolean;
 private: boolean;
}) => (initialValue: unknown) => unknown | void;

Since class fields already return an initializer, they do not receive addInitializer and cannot add additional initialization logic.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jan 19, 2024
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 5.4.0 milestone Jan 19, 2024
@rbuckton rbuckton added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Jan 19, 2024
@rbuckton
Copy link
Member

All current decorators, including class fields, support addInitializer. The explainer text is out of date compared to the actual specification text at https://arai-a.github.io/ecma262-compare/?pr=2417.

As you can see from CreateDecoratorContext, addInitializer is attached unconditionally on step 12:

CreateDecoratorContext algorithm steps

@rbuckton rbuckton closed this as not planned Won't fix, can't repro, duplicate, stale Jan 19, 2024
@phiresky
Copy link
Author

Ah. Thanks, then I'll open an issue with swc instead.

@rbuckton
Copy link
Member

You may also want to open an issue or PR on the proposal repo to fix the explainer.

@phiresky
Copy link
Author

Good idea, opened an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants