-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Decorators #2249
Comments
Excuse me from what I understand of the spec, we won't be able to do:
Am I right ? |
How does type serialization work with rest arguments? @F()
class Foo {
constructor(...args: string[]) {
}
}
function F(@paramterTypes types?: Function[]) {
return function (target) {
target.paramterTypes = types; // ???
}
} |
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 Are decorator factories intended to be classes that implement the interfaces found in B? |
What is the rule for refining the interpretation of CoverMemberExpressionSquareBracketsAndComputedPropertyName? |
I noticed many of the typings have |
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. |
For the decorated exports, what is |
This is a dup of #1557 |
It's not really a dupe, as #1557 was for a different design. This issue is for the decorators design being implemented now. |
My mistake. |
For decorator on function expression, could we not do something like : @F("color") @G
function myFunc() {
doSomething();
} transformed in : var _t = function() {
doSomething();
}
_t = F("color")(_t = G(_t) || _t) || _t;
function myFunc() {
return _t.apply(this, arguments)
} It's a bit bother some to have to right every function like : const myFunc = function () {} You loose hoisting, and |
Implementation added in PR #2399 |
Updates: Proposal updated, and added link to the @wycats ES7 JavaScript decorators. |
saddened that it became a class only thing ... |
@fdecampredon with your proposal for functions, seems like you still lose the hoisting. |
@JsonFreeman why ? if you insert import something from 'something';
myFunc(something.something());
@F("color") @G
function myFunc() {
doSomething()
} import something from 'something';
var _t = function() {
doSomething();
}
_t = F("color")(_t = G(_t) || _t) || _t;
myFunc(something.something());
function myFunc() {
return _t.apply(this, arguments)
} Also even if my proposal has a lot of issues, I would seriously like to be able to use decorators on function (even if I have to use variable assigned function) and lose hoisting. |
@fdecampredon this does not work for the general case, as the decorators are expressions themselves. e.g. myFunc(); // assumes function declaration is hoisted
var dec = (t) => t; // defininig a decorator
@dec
function myFunc() {} if you hoist the function declaration and application of the decorator then you break the decorator. if you only hoist the function declaration, but not the decorator application you can witness the function in an undecorated state. no appealing solutions here. this is the same issue as with class declaration extend clause, which in ES6 is an expression. the result was not hoisting the class declaration, just the symbol (akin to var declaration, but not function declarations) |
Oups didn't think about it thank you @mhegazy.
Loosing hoisting is sure a drawback, but I find it damageable to transform it into an class only feature when it would have use case for other construct. |
Let's see what the desired set of constraints seem to imply:
The only resolution I can see for this is the following: For function decorators, we only allow something of the form |
The problem breaking hoisting rules is that it is surprising. If you are writing javascript for a while you expect function declarations to be available before they are lexically declared; now by adding a seemingly simple syntactic marker (the decorator) this fundamental nature of function declaration is altered. Having said that, the ES7 proposal is still in its initial stages, so I expect it to evolve and expand; so it is conceivable that the final proposal would include functions in some form. |
I do think they should be hoisted. I am saying that the only decorations we allow on functions are decorations that are definitely themselves hoisted. Namely identifiers that reference function declarations. But there is another problem here. It is actually impossible to simultaneously hoist all decorated functions and ensure that they are not observed in their undecorated state. The problem can be seen with a decorator cycle. @dec1
function dec2(target: Function) {
// Do stuff
}
@dec2
function dec1(target: Function) {
// Do stuff
} Even if both functions are hoisted, which one gets decorated first? If dec2 gets decorated first, then dec1 will not itself be decorated by the time it is applied to dec2. So we would have to choose between the following:
While I don't like either of these, I don't even think anything else is possible. |
This is the JS proposal. so the engine would not know if the expression refers to a function declaration or not, with static analysis we could tell though. consider this: @dec1
function dec2(target: Function) {
// Do stuff
}
dec2 = undefined;
@dec2
function dec1(target: Function) {
// Do stuff
} |
@cybrown Yes, it uses the property descriptor for methods and accessors. I tested on plain properties (fields w/o accessors) only. But it seems that decorators can be allowed in ES3 for properties (w/o accessors) and classes. It would be helpful. |
And a fake property descriptor can be used for methods when targeting ES3. Something like |
@sccolbert I see. That makes sense. Incidentally, TypeScript is working on improved this typing for functions and methods. I wonder if that would be of any help here. Although I suppose typing is not the issue for you, it's runtime semantics. |
@JsonFreeman Improved this typing sounds intriguing for some of my other use cases. Do you have any more info on that? |
I think the most developed discussion on this typing is at #3694. |
Cheers! |
error TS1207: Decorators cannot be applied to multiple get/set accessors of the same name. @get
public get myValue():any{...}
@set
public set myValue(value:any){...} code above is not allowed even it make more sense compare to @get
@set
public get myValue():any{...}
public set myValue(value:any){...} |
Getter and setter are defined in one call to Obect.defineProperty. This rather a js quirk, the declaration of set and get though separate, really are the same property declaration. The error check in the compiler is to alert users when thinking of them separately; the decorators are applied only once to the property descriptor. |
just wondering since the compiler can sense the get and set with same name and combine into single Object.defineProperty, why not also combine the decorator? thank you |
@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: @F
@G
class X {} Is approximately: F(G(X)) The compositionality of decorators breaks down when you decorate both the getter and the setter: class C {
@F
set X(value) {}
@G
get X() {}
} How do |
@rbuckton thank you so much for detailed explanation |
Where is the documentation for this? and care to link the implementation commit? Thanks. |
@mhegazy What is the status on the implementation of the latest version of the spec. I understand there are some changes there. |
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 @wycats on the new proposal. |
@omeid, you can find documentation at https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md |
@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! |
Function decoration is need of course. |
Decorator targets:
Class constructor
desugars to:
Methods
desugars to:
Static method
desugars to:
Properties
desugars to:
Method/Accessor formal parameter
desugars to:
Where the __decorate is defined as:
Decorator signatures:
A valid decorator should be:
Notes:
var x = dec(function () { });
The text was updated successfully, but these errors were encountered: