Repository navigation
Decorators #2249
Copy link
Copy link
Closed
Labels
CommittedThe team has roadmapped this issueThe team has roadmapped this issueES NextNew featurers for ECMAScript (a.k.a. ESNext)New featurers for ECMAScript (a.k.a. ESNext)FixedA PR has been merged for this issueA PR has been merged for this issueSuggestionAn idea for TypeScriptAn idea for TypeScript
Description
ES7 proposal
The ES7 proposal for decorators can be found here: https://github.com/wycats/javascript-decorators
The ES7 proposal serves as the base of this proposal. Below are notes about how the type system
Decorator targets:
Class constructor
@F("color")
@G
class Foo {
}desugars to:
var Foo = (function () {
function Foo() {
}
Foo = __decorate([F("color"), G], Foo);
return Foo;
})();Methods
class Foo {
@F(color)
@G
bar() { }
}desugars to:
var Foo = (function () {
function Foo() {
}
Foo.prototype.bar = function () {
};
Object.defineProperty(Foo.prototype, "bar", __decorate([F(color), G], Foo.prototype, "bar", Object.getOwnPropertyDescriptor(Foo.prototype, "bar")));
return Foo;
})();Static method
class Foo {
@F("color")
@G
static sMethod() {}
}desugars to:
var Foo = (function () {
function Foo() {
}
Foo.sMethod = function () {
};
Object.defineProperty(Foo, "sMethod", __decorate([F("color"), G], Foo, "sMethod", Object.getOwnPropertyDescriptor(Foo, "sMethod")));
return Foo;
})();Properties
class Foo {
@F("color")
@G
prop: number;
}desugars to:
var Foo = (function () {
function Foo() {
}
__decorate([F("color"), G], Foo.prototype, "prop");
return Foo;
})();Method/Accessor formal parameter
class Foo {
method(@G a, @F("color") b) {}
}desugars to:
var Foo = (function () {
function Foo() {
}
Foo.prototype.method = function (a, b) {
};
__decorate([G], Foo.prototype, "method", 0);
__decorate([F("color")], Foo.prototype, "method", 1);
return Foo;
})();Where the __decorate is defined as:
var __decorate = this.__decorate || function (decorators, target, key, value) {
var kind = typeof (arguments.length == 2 ? value = target : value);
for (var i = decorators.length - 1; i >= 0; --i) {
var decorator = decorators[i];
switch (kind) {
case "function": value = decorator(value) || value; break;
case "number": decorator(target, key, value); break;
case "undefined": decorator(target, key); break;
case "object": value = decorator(target, key, value) || value; break;
}
}
return value;
};Decorator signatures:
A valid decorator should be:
- Assignable to one of the Decorator types (ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator) as described below.
- Return a value (in the case of class decorators and method decorator) that is assignable to the decorated value.
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;Notes:
- Decorating a function declaration is not allowed as it will block hoisting the function to the top of the scope, which is a significant change in semantics.
- Decorating function expressions and arrow functions are not supported. The same effect can be achived by applying the decorator function as
var x = dec(function () { }); - Decorating function formal parameters is currently not part of the ES7 proposal.
- Decorators are not allowed when targeting ES3
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
CommittedThe team has roadmapped this issueThe team has roadmapped this issueES NextNew featurers for ECMAScript (a.k.a. ESNext)New featurers for ECMAScript (a.k.a. ESNext)FixedA PR has been merged for this issueA PR has been merged for this issueSuggestionAn idea for TypeScriptAn idea for TypeScript
Activity
fdecampredon commentedon Mar 7, 2015
Excuse me from what I understand of the spec, we won't be able to do:
Am I right ?
ivogabe commentedon Mar 7, 2015
How does type serialization work with rest arguments?
MgSam commentedon Mar 7, 2015
Using decorators seems straightforward enough, but I found the sections about declaring them to be confusing. C.4 says decorators need to be annotated with
@decorator, but not a single one of the examples actually shows this happening.Are decorator factories intended to be classes that implement the interfaces found in B?
JsonFreeman commentedon Mar 7, 2015
What is the rule for refining the interpretation of CoverMemberExpressionSquareBracketsAndComputedPropertyName?
JsonFreeman commentedon Mar 7, 2015
I noticed many of the typings have
Function | Objectat various points, but these will degenerate to Object at type check time. What is the reason to have Function there?JsonFreeman commentedon Mar 7, 2015
I am not crazy about the terms DecoratorFunction vs DecoratorFactory. I'd much rather follow the nomenclature of generators, which has Generator and GeneratorFunction. With this scheme, we would rename DecoratorFunction to Decorator, and DecoratorFactory to DecoratorFunction.
JsonFreeman commentedon Mar 7, 2015
For the decorated exports, what is
[lookahead ≠ @]for? Can HoistableDeclaration and ClassDeclaration actually start with a@?jayphelps commentedon Mar 8, 2015
This is a dup of #1557
JsonFreeman commentedon Mar 8, 2015
It's not really a dupe, as #1557 was for a different design. This issue is for the decorators design being implemented now.
jayphelps commentedon Mar 8, 2015
My mistake.
fdecampredon commentedon Mar 9, 2015
For decorator on function expression, could we not do something like :
transformed in :
It's a bit bother some to have to right every function like :
You loose hoisting, and
function.name124 remaining items
rbuckton commentedon Sep 21, 2015
Tako Little (@TakoLittle): The reason we don't do this today partially stems from how decorators are composed. Decorators follow the same principals as Mathematical function composition, where (f ∘ g)(x) is composed as f(g(x)). In the same sense, it can be thought that:
Is approximately:
The compositionality of decorators breaks down when you decorate both the getter and the setter:
How do
FandGcompose here? Is it based purely on document order (i.e.F(G(X)))? Are each set of decorators for the getter and the setter discrete, and then executed in document order (i.e.G(F(X)))? Dogetandsetimply any specific ordering (i.e. is thegetalways before thesetor vice versa)? Until we're 100% certain the most consistent approach that doesn't surprise users, or have a well documented approach that is part of the decorators proposal with at least stage 2 or better acceptance within ECMA-262, we feel it is best to be more restrictive and error here as it allows us to relax that restriction at a later date without introducing a breaking change that could easily go unnoticed and possibly result in unexpected behaviors at runtime.TakoLittle commentedon Sep 21, 2015
Ron Buckton (@rbuckton) thank you so much for detailed explanation
TS team great work!! ^^d
omeid commentedon Feb 20, 2016
Where is the documentation for this? and care to link the implementation commit?
Thanks.
EisenbergEffect commentedon Feb 20, 2016
Mohamed Hegazy (@mhegazy) What is the status on the implementation of the latest version of the spec. I understand there are some changes there.
mhegazy commentedon Feb 22, 2016
This issue tracked the original version of the proposal. since this is completed we are closing this issue. for any updates to the spec, we will log new issues and outline all the breaking changes. I do not think the proposal is at a place now to be ready for us to jump on it. We are working closely with Yehuda Katz (@wycats) on the new proposal.
mhegazy commentedon Feb 22, 2016
Omeid Matten (@omeid), you can find documentation at https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md
EisenbergEffect commentedon Feb 23, 2016
Mohamed Hegazy (@mhegazy) Thank you for the update. I'd love to stay informed. When you create the new issue for the spec update, please link it here so I can be notified and follow. The Aurelia community makes heavy use of decorators and we'll want to synchronize with both TypeScript and Babel on the update. Again, thanks for the great work the TS team is doing!
wclr commentedon Aug 27, 2016
Function decoration is need of course.
Are there also plans for decorating of other objects in the code?