- 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