-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
Implement decorator metadata proposal #53461
Comments
Nevermind, you refer to an actual ES proposal. But that is only stage 2, usually the team waits for at least stage 3. |
Yes, but like I mentioned the metadata proposal just got consensus on the approach to enable it to go to Stage 3 very soon. An issue like this can be used to track some work even before that work could be done or shipped. |
Tentatively scheduling for TypeScript 5.2. Luckily, that's not too far off anyway. |
Please. Please. Please. Please. Please. Please. Please. @DanielRosenwasser I will send your team a cake. Or, if you like other tasties, let me know. Clearly I'm not above bribery when it comes to decorator metadata π€£ /cc @chrisdholt |
Stage 3 is official!!! π |
The downlevel emit for this is fairly simple, and should work with the existing helpers. When I wrote the given @dec
class C {
} we used to emit let C = (() => {
let _classDecorators = [dec];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
var C = class {
static {
__esDecorate(null, _classDescriptor = { value: this }, _classDecorators, { kind: "class", name: this.name }, null, _classExtraInitializers);
C = _classThis = _classDescriptor.value;
__runInitializers(_classThis, _classExtraInitializers);
}
};
return C = _classThis;
})(); But in the future, we will emit this instead: let C = (() => {
let _classDecorators = [dec];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
var C = class {
static {
const metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : undefined;
__esDecorate(null, _classDescriptor = { value: this }, _classDecorators, { kind: "class", name: this.name, metadata }, null, _classExtraInitializers);
C = _classThis = _classDescriptor.value;
if (metadata) Object.defineProperty(C, Symbol.metadata, { configurable: true, writable: true, value: metadata });
__runInitializers(_classThis, _classExtraInitializers);
}
};
return C = _classThis;
})(); Metadata availability will be conditional on the presence of |
YES!!!! Awesome work everyone. @DanielRosenwasser please reach out to me on twitter, linkedin, etc. I really would like to thank the team somewhow. |
@rbuckton would #54657 be in the latest nightly? I'm trying to use metadata, and while it's in the typings, it appears to always be edit to add: I don't see a way to choose libs in the playground, but I did add |
Have you polyfilled (Symbol as any).metadata ??= Symbol.for("Symbol.metadata"); Also, you can use |
I just figured that out, thanks! |
@rbuckton I got caught out by The current developer experience is:
Whereas if
With the latter case, you run into the actual problem, not a side-effect of the problem. |
I agree that seeing an error that I think changing the metadata initialization from this: const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
// ...
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); to this: const _metadata = Object.create(null);
// ...
if (typeof Symbol === "function" && Symbol.metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); Would ensure that |
Yep, +1 to that implementation |
If Having I could see adding a documentation comment to the |
I guess if browsers shipped decorators without metadata, then Yeah, improved documentation seems reasonable. |
The current approach also allows you to write the following shim in your code to enable // metadataShim.ts
export {};
declare global {
interface SymbolConstructor {
readonly metadata: unique symbol;
}
}
Symbol.metadata ??= Symbol.for("Symbol.metadata");
// yourCode.ts
import "./metadataShim.js";
... The above code would also remove the |
This is a really good point. We already do this in Lit 3.0 with a dev-mode warning when metadata is undefined telling people that they need to upgrade their compiler. |
Suggestion
Implement decorator metadata
π Search Terms
decorator metadata
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
Now that decorators are shipping in TypeScript and decorator metadata has reached consensus on the approach needed for it to proceed to Stage 3, it seems like it may be time to implement metadata.
π Motivating Example
There are examples on the metadata repo, but a quick one is storing information about a class member to be used by the class's base class. Here we generate a custom element's
observedAttributes
by decorating fields:π» Use Cases
There are many use cases in the various decorators repositories and documents. Generally any time that some other API besides the decorated one needs information about the decorated items, you will need metadata.
It's worth noting that many libraries can't use decorators until metadata is implemented.
The text was updated successfully, but these errors were encountered: