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

Private name "#..." must be declared in an enclosing class when referencing from decorator #3394

Closed
akcyp opened this issue Sep 18, 2023 · 2 comments

Comments

@akcyp
Copy link

akcyp commented Sep 18, 2023

esbuild version: 0.19.3

Context: Private class fields should be only available from inside of class declaration. We can move accessor to outside context but still we have to declare it "inside" class declaration, like in this example:

let x
class A {
    #test = 42;
    static {
        x = (obj) => obj.#test;
    }
}
console.log(x(new A)); // 42
// Works correctly in both typescript and esbuild compiler

The problem: When using decorators syntax we cannot reffer to private fields. Example:

type AttributeOptions<T> = {
  onChange?: (this: T, value: string, oldValue: string) => void;
};

const Attribute = <T, V>(options: AttributeOptions<T> = {}) => (
  value: ClassAccessorDecoratorTarget<T, V>,
  _: ClassAccessorDecoratorContext<T, V>,
): ClassAccessorDecoratorResult<T, V> => {
  const { get, set } = value;
  return {
    get() {
      return get.call(this);
    },
    set(value) {
      const oldValue = get.call(this);
      set.call(this, value);
      options.onChange?.call(this, value as string, oldValue as string);
    },
  };
};

class CustomHTMLElement {
  #test = 'test';
  @Attribute({
    onChange() {
      console.log(this.#test); // <- fails on esbuld
    }
  }) accessor field = '';
}

new CustomHTMLElement().field = '';

Typescript working example: Playground Link

Esbuild not working example: Playground Link

image

@evanw
Copy link
Owner

evanw commented Sep 18, 2023

First of all, the code you wrote appears to be intended for JavaScript decorators and not for TypeScript experimental decorators. They are two different features with almost-identical syntax but with different semantics. This is a problem because esbuild currently only implements TypeScript experimental decorators (see #104 for the open issue about esbuild adding support for JavaScript decorators). So your code wouldn't work even if this error didn't happen.

In case you are talking about how to run analogous code written for TypeScript experimental decorators: TypeScript has bugs and semantic inconsistencies in the design of this feature (specifically experimental decorators) that are causing this problem. See microsoft/TypeScript#48515 for details. I'm still not sure what exactly to do about this.

@akcyp
Copy link
Author

akcyp commented Sep 19, 2023

Yeah, you're right, I was trying to use stage 3 decorators syntax. The implementation of decorators has been taking a long time, I guess it is not an easy task, especially implementing them without full specifications. As I understand it, as long as the decorators are not in the final stage and typescript has syntax errors related to this feature, we should not expect basic support? Anyway, thank you for the explanation and quick reply, you can close this issue or keep it for reference.

@evanw evanw closed this as completed in 0d9f765 Nov 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants