{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2249","labels_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2249/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2249/comments","events_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2249/events","html_url":"https://github.com/Microsoft/TypeScript/issues/2249","id":60187635,"number":2249,"title":"Decorators","user":{"login":"rbuckton","id":3902892,"avatar_url":"https://avatars.githubusercontent.com/u/3902892?v=3","gravatar_id":"","url":"https://api.github.com/users/rbuckton","html_url":"https://github.com/rbuckton","followers_url":"https://api.github.com/users/rbuckton/followers","following_url":"https://api.github.com/users/rbuckton/following{/other_user}","gists_url":"https://api.github.com/users/rbuckton/gists{/gist_id}","starred_url":"https://api.github.com/users/rbuckton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rbuckton/subscriptions","organizations_url":"https://api.github.com/users/rbuckton/orgs","repos_url":"https://api.github.com/users/rbuckton/repos","events_url":"https://api.github.com/users/rbuckton/events{/privacy}","received_events_url":"https://api.github.com/users/rbuckton/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/ES7","name":"ES7","color":"bfd4f2"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/In%20Discussion","name":"In Discussion","color":"556b75"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Spec","name":"Spec","color":"207de5"},{"url":"https://api.github.com/repos/Microsoft/TypeScript/labels/Suggestion","name":"Suggestion","color":"006b75"}],"state":"open","locked":false,"assignee":{"login":"rbuckton","id":3902892,"avatar_url":"https://avatars.githubusercontent.com/u/3902892?v=3","gravatar_id":"","url":"https://api.github.com/users/rbuckton","html_url":"https://github.com/rbuckton","followers_url":"https://api.github.com/users/rbuckton/followers","following_url":"https://api.github.com/users/rbuckton/following{/other_user}","gists_url":"https://api.github.com/users/rbuckton/gists{/gist_id}","starred_url":"https://api.github.com/users/rbuckton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rbuckton/subscriptions","organizations_url":"https://api.github.com/users/rbuckton/orgs","repos_url":"https://api.github.com/users/rbuckton/repos","events_url":"https://api.github.com/users/rbuckton/events{/privacy}","received_events_url":"https://api.github.com/users/rbuckton/received_events","type":"User","site_admin":false},"milestone":null,"comments":104,"created_at":"2015-03-07T03:14:53Z","updated_at":"2015-05-30T04:31:06Z","closed_at":null,"body":"> ## ES7 proposal\r\nThe ES7 proposal for decorators can be found here: https://github.com/wycats/javascript-decorators\r\nThe ES7 proposal serves as the base of this proposal. Below are notes about how the type system \r\n\r\n## Decorator targets:\r\n\r\n### Class constructor\r\n```ts\r\n@F(\"color\")\r\n@G\r\nclass Foo {\r\n}\r\n```\r\ndesugars to:\r\n\r\n```js\r\nvar Foo = (function () {\r\n    function Foo() {\r\n    }\r\n    Foo = __decorate([F(\"color\"), G], Foo);\r\n    return Foo;\r\n})();\r\n```\r\n\r\n### Methods\r\n```ts\r\nclass Foo {\r\n  @F(color)\r\n  @G\r\n  bar() { }\r\n}\r\n```\r\ndesugars to:\r\n\r\n```js\r\nvar Foo = (function () {\r\n    function Foo() {\r\n    }\r\n    Foo.prototype.bar = function () {\r\n    };\r\n    Object.defineProperty(Foo.prototype, \"bar\", __decorate([F(color), G], Foo.prototype, \"bar\", Object.getOwnPropertyDescriptor(Foo.prototype, \"bar\")));\r\n    return Foo;\r\n})();\r\n```\r\n\r\n## Static method\r\n```ts\r\nclass Foo {\r\n    @F(\"color\")\r\n    @G\r\n    static sMethod() {}\r\n}\r\n```\r\ndesugars to:\r\n\r\n```js\r\nvar Foo = (function () {\r\n    function Foo() {\r\n    }\r\n    Foo.sMethod = function () {\r\n    };\r\n    Object.defineProperty(Foo, \"sMethod\", __decorate([F(\"color\"), G], Foo, \"sMethod\", Object.getOwnPropertyDescriptor(Foo, \"sMethod\")));\r\n    return Foo;\r\n})();\r\n```\r\n\r\n### Properties\r\n```ts\r\nclass Foo {\r\n    @F(\"color\")\r\n    @G\r\n    prop: number;\r\n}\r\n```\r\ndesugars to:\r\n\r\n```js\r\nvar Foo = (function () {\r\n    function Foo() {\r\n    }\r\n    __decorate([F(\"color\"), G], Foo.prototype, \"prop\");\r\n    return Foo;\r\n})();\r\n```\r\n\r\n### Method/Accessor formal parameter\r\n```ts\r\nclass Foo {\r\n    method(@G a, @F(\"color\") b) {}\r\n}\r\n```\r\ndesugars to:\r\n\r\n```js\r\nvar Foo = (function () {\r\n    function Foo() {\r\n    }\r\n    Foo.prototype.method = function (a, b) {\r\n    };\r\n    __decorate([G], Foo.prototype, \"method\", 0);\r\n    __decorate([F(\"color\")], Foo.prototype, \"method\", 1);\r\n    return Foo;\r\n})();\r\n```\r\n\r\nWhere the __decorate is defined as:\r\n```js\r\nvar __decorate = this.__decorate || function (decorators, target, key, value) {\r\n    var kind = typeof (arguments.length == 2 ? value = target : value);\r\n    for (var i = decorators.length - 1; i >= 0; --i) {\r\n        var decorator = decorators[i];\r\n        switch (kind) {\r\n            case \"function\": value = decorator(value) || value; break;\r\n            case \"number\": decorator(target, key, value); break;\r\n            case \"undefined\": decorator(target, key); break;\r\n            case \"object\": value = decorator(target, key, value) || value; break;\r\n        }\r\n    }\r\n    return value;\r\n};\r\n```\r\n## Decorator signatures:\r\nA valid decorator should be:\r\n1. Assignable to one of the Decorator types (ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator) as described below.\r\n2. Return a value (in the case of class decorators and method decorator) that is assignable to the decorated value.\r\n\r\n```ts\r\ndeclare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;\r\ndeclare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;\r\ndeclare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;\r\ndeclare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;\r\n```\r\n\r\n### Notes:\r\n\r\n- 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. \r\n- 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 () { });` \r\n- Decorating function formal parameters is currently not part of the ES7 proposal.\r\n- Decorators are not allowed when targeting ES3\r\n"},"comment":{"url":"https://api.github.com/repos/Microsoft/TypeScript/issues/comments/106987578","html_url":"https://github.com/Microsoft/TypeScript/issues/2249#issuecomment-106987578","issue_url":"https://api.github.com/repos/Microsoft/TypeScript/issues/2249","id":106987578,"user":{"login":"lucasmciruzzi","id":3979433,"avatar_url":"https://avatars.githubusercontent.com/u/3979433?v=3","gravatar_id":"","url":"https://api.github.com/users/lucasmciruzzi","html_url":"https://github.com/lucasmciruzzi","followers_url":"https://api.github.com/users/lucasmciruzzi/followers","following_url":"https://api.github.com/users/lucasmciruzzi/following{/other_user}","gists_url":"https://api.github.com/users/lucasmciruzzi/gists{/gist_id}","starred_url":"https://api.github.com/users/lucasmciruzzi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lucasmciruzzi/subscriptions","organizations_url":"https://api.github.com/users/lucasmciruzzi/orgs","repos_url":"https://api.github.com/users/lucasmciruzzi/repos","events_url":"https://api.github.com/users/lucasmciruzzi/events{/privacy}","received_events_url":"https://api.github.com/users/lucasmciruzzi/received_events","type":"User","site_admin":false},"created_at":"2015-05-30T04:31:06Z","updated_at":"2015-05-30T04:31:06Z","body":"**Question:** Can the decorators be used to modify the behavior of a plain object method, like...\r\n````typescript\r\nvar isCreatorUser = () => {  /* code that verifies if user is the creator */ },\r\n    isAdminUser = () => { /* code that verifies if user is admin */ },\r\n\r\nvar routeConfig = {\r\n    get() {},\r\n    @isCreatorUser patch() {},\r\n    @isAdminUser @isCreatorUser delete() {}\r\n};\r\n````\r\n... and if not, why? It will be really useful."}}