- From: Joe Pea <notifications@github.com>
- Date: Thu, 16 Nov 2023 01:45:13 -0800
- To: WICG/webcomponents <webcomponents@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <WICG/webcomponents/issues/1036/1814102675@github.com>
Oops, I realized that with `new SomeElement` there's actually no way for the browser to call an internals callback like it could with `document.createElement('some-element')` or during parsing, unless we wait for decorators.
I'm guessing this is why the internals callback idea was not viable (decorators were not even stage 3 at the time).
Only a class decorator can ensure that the internals callback is called during construction with `new` _after the user constructor so that private fields are ready_.
The method decorator idea won't work: it can add an initializer in which could call the internals callback during the user's constructor but the initializer runs _before_ fields are initialized, which means users will not be able to use private fields in the callback because they'll get a runtime error:
```ts
function methodDeco(value: unknown, context: ClassMethodDecoratorContext) {
context.addInitializer(function(this: any) {
this[context.name]({foo: 123})
})
}
class MyClass {
#foo: any
@methodDeco receiveInternals(obj: {foo: number}) {
this.#foo = obj
}
logInternals() {console.log(this.#foo)}
}
new MyClass().logInternals() // TypeError: Cannot write private member to an object whose class did not declare it
```
[TS playground](https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABAWwKZQBZwCYBFURwAUAbgIYA2IqAXIuANZhwDuYANIoWFKgB5Q6AYQpkAzmICy6LHgJwATmSiKhCXgICUiAN4AoRF3X8oAOjLZsASTAxYlGAC9UCoqEiwERTDDF0yYACe2vqGhj5iANrcGmZgZGgAukQ6wHBwdACMAEwAzAC+mgaIhXr5enoQohKIkoEi4mK6xQDEaRmIAYEVhgACaJg4+ISICgSoMCSoNrwK8RRiRHAARgBWdKnpdGAgyMsuhc1hiBGmbemIALyIK6vF5cUUcADmMy7ziyHcYnAUqKZPZ7eDC+M7tTTlB5gVAsWr1aqfAEvN5zSifIA) (hit "Run" to see the error)
A class decorator would work like so:
```ts
function classDeco<T extends new (...args: any[]) => any>(value: T, context: ClassDecoratorContext) {
return class extends value {
constructor(...args: any[]) {
super(...args)
this.internalsCallback({foo: 123})
}
}
}
@classDeco
class MyClass {
#foo: any
internalsCallback(obj: {foo: number}) {
this.#foo = obj
}
logInternals() {console.log(this.#foo)}
}
new MyClass().logInternals()
```
[TS playground](https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABBANgQwM4YCIFMJwA8AKorgB5S5gAmGiYuA7ogBQB0naATgOYYAuRGjABPANoBdAJSIAvAD5hYhawBuaFCFxDiAGmQIqlIQGF0WPAW5oocbqaMUosgN4AoRIm64oIbkiomPTO1HSIGlq4iB5eXgRgGFDcIND2HFx8gsoSMjGecV4YIAAOuNwZ7Dz80gWFUAAWMBjsMGBUAZoYppooAEZoEADWrK7AcHBCAIwATADMAL61hQsFq6vuAAJBlvhw7jv0ALKi5sH5XgDE45M57gVtHWBdPSj9gyNwfQBWQmMTQjAIAAtn1yksLnFGs12NcJvJEF9vmt7l4UHBeABJdrlZ4oDCsNwJDBwFC4djo3isaEtOFwaTre6MFgnM5YQkUjHYp5dQlAA) (click "Run" and see console output)
--
Reply to this email directly or view it on GitHub:
https://github.com/WICG/webcomponents/issues/1036#issuecomment-1814102675
You are receiving this because you are subscribed to this thread.
Message ID: <WICG/webcomponents/issues/1036/1814102675@github.com>
Received on Thursday, 16 November 2023 09:45:19 UTC