Decorators Normative Update: Flexible Initializers
Chris Hewell Garrett
2022-06
Current
Decorators can add initializers with the `addInitializer` method of the context object. These added-initializers run in 1 of 3 phases, depending on the value being decorated.
- Instance added-initializers run prior to field assignment on every instance
- Static added-initializers run prior to static field assignment on the class itself
- Class added-initializers run immediately after the class is fully defined (e.g. after static fields have been assigned)
@dec
class C {
foo = 123;
@dec bar() {}
static foo = 123;
@dec static bar() {}
}
// Approximate transpilation
class C {
foo = (runInstanceInitializers(this), 123);
bar() {}
static foo = (runStaticInitializers(this), 123);
static bar() {}
}
runClassInitializers(C);
Proposed
First parameter to `addInitializer` determines placement. Can be "instance", "static", or "class". Benefits:
- Provides more flexibility. Instance methods often require some amount of static initialization (ex: props on web-components)
- Metadata can be added by instance decorators with static/class initializers. No need for Symbol.metadata or additional APIs (though there are still benefits for them, will continue to explore separately)
function dec(value, context) {
context.addInitializer('instance', () => {
console.log('instance!')
});
context.addInitializer('static', () => {
console.log('static!')
});
context.addInitializer('class', () => {
console.log('class!')
});
}
@dec class C {}
// static! class!
new C();
// instance!
Decorators Normative Changes: Flexible Initializers
By pzuraq
Decorators Normative Changes: Flexible Initializers
- 797