Private name "#..." must be declared in an enclosing class when referencing from decorator #3394
Closed
Description
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
Metadata
Assignees
Labels
No labels