Typescript: decorators in object literals not working

Created on 24 Nov 2015  路  18Comments  路  Source: microsoft/TypeScript

_From @pascalopitz on November 19, 2015 11:43_

I am getting a parsing error for decorators on object literal properties. My jsconfig.json looks like this:

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "experimentalDecorators": true
    }
}

This code compiles okay in babel 5.8.12 using the "es7.decorators" extension.
Can I somehow make this work?

image

_Copied from original issue: Microsoft/vscode#201_

Committed Decorators Suggestion

Most helpful comment

Hi, team, we've been heavily used ES decorators, especially decorators for object literals in our products, currently any code after blocks decorated by such decorators, could not be parsed correctly by VSCode; it keeps prompting [js] ';' expected. or [js] Declaration or statement expected., which seem annoying.

With some search, we found this issue, however a year has passed since last update of the issue. ES standards are evolving slower than we expected but babel-plugin-transform-decorators-legacy is still popular. Seems a lot of JS open source libs depend on this legacy decorators for object literals.

Is it possible for TS or VSCode to add a special setting to allow the decorators for object literals in JS code (e.g. experimentalDecoratorsForObjectLiterals), regardless the ES standard? It's ok to keep the legacy/non-standard warnings, but for minimal the code after the decorated blocks should be parsed correctly.

Thanks.

All 18 comments

This is currently not supported. it is only supported on classes. i suspect will add support after the next TC39 meeting, just to have the proposal stabilizes.

Hi there. I am not sure why this has been moved accross to TS, since I am not using TS at all? Is the jsconf also using the TS parser?

Yes - some js services in vscode are based on the typescript language service.

It appears that it is firmly part of the proposal now. I see that "Decorators for function expressions/arrow functions" are on the roadmap for 2.0 but not this.

The decorator proposal is changing a lot. there are some fundamental changes in how decorators are applied. we will need to stage all these changes and make sure they all land around the same time. I do not think we will be changing anything in the decorator implementation until these changes are finalized.

Hi, team, we've been heavily used ES decorators, especially decorators for object literals in our products, currently any code after blocks decorated by such decorators, could not be parsed correctly by VSCode; it keeps prompting [js] ';' expected. or [js] Declaration or statement expected., which seem annoying.

With some search, we found this issue, however a year has passed since last update of the issue. ES standards are evolving slower than we expected but babel-plugin-transform-decorators-legacy is still popular. Seems a lot of JS open source libs depend on this legacy decorators for object literals.

Is it possible for TS or VSCode to add a special setting to allow the decorators for object literals in JS code (e.g. experimentalDecoratorsForObjectLiterals), regardless the ES standard? It's ok to keep the legacy/non-standard warnings, but for minimal the code after the decorated blocks should be parsed correctly.

Thanks.

Hi, @mhegazy , may I ask whether has this issue even been part of TypeScript 2.1 milestone? Thanks.

This issue is under the Future milestone currently, meaning it is on our list, but we have no ETA at the moment .

Thanks for telling @mhegazy . Btw, what do you think about my previous question?

Is it possible for TS or VSCode to add a special setting to allow the decorators for object literals in JS code (e.g. experimentalDecoratorsForObjectLiterals), regardless the ES standard? It's ok to keep the legacy/non-standard warnings, but for minimal the code after the decorated blocks should be parsed correctly.

VSCode uses TS to power the JS/TS language service. If the feature is supported in TS, it will light up in future VSCode versions.

Keep in mind that decorators are currently a stage 2 proposal TC39, and not a ratified feature. we do plan on revisiting our decorator support soon, and implementing the new proposal. once we do that, we should have a clear resolution for this feature.

@mhegazy can you please provide some approximated time, how long will it take? it would be really helpful for us to consider building upon that, (like if it's another 3 years then we will have to find some workaround)

@Durisvk as Mohamed stated, this is contingent on the Proposal progressing to Stage 3 with TC39. It is still at Stage 2. You can get the status and progress of the proposal here where you can participate in the discussion. It is being discussed actively at every TC39 meeting and has a lot of focus.

@kitsonk I didn't find any mention (in this proposal you've provided) about a decorating object literals. It's again only focused on the classes, class properties, class methods and methods params. No object literal at all. I don't even see a place where I can participate in the discussion (should I create issue on that github page or how to discuss?). I don't know what TC39 means.

@Durisvk TC39 is the technical committee responsible for ECMAScript/ECMA-262 (the standard behind JavaScript). Their guidelines on contributing are documented in the proposals repo I linked to. They also provide documentation of the proposal process.

I should not say this, but technically you can manually apply a decorator on literal object property as well as on non-const enum member

import "reflect-metadata";

let dataKey = Symbol('myData');

let setMetaData = (Reflect as any).metadata(dataKey, 'DataDataData');
let getMetadata = (type: any, propertyKey: string) =>
  (Reflect as any).getMetadata(dataKey, type, propertyKey);

class MyClass {
  @setMetaData
  static one = 1;
}
console.log(getMetadata(MyClass, 'one')); // DataDataData

enum MyEnum {
  // @setMetaData // Disallowed
  one = 1
}
// @ts-ignore
__decorate([setMetaData], MyEnum, 'one', void 0); // Manual decoration
console.log(getMetadata(MyEnum, 'one')); // DataDataData

let myLiteral = {
  // @setMetaData // Disallowed
  one: 1
};
// @ts-ignore
__decorate([setMetaData], myLiteral, 'one', void 0); // Manual decoration
console.log(getMetadata(myLiteral, 'one')); // DataDataData

@shlangus Yeah but when you're building a library you don't want the programmers who use it to do this kind of hack

@mhegazy Is this going to be supported eventually? It'd be nice to not do object <-> class mapping in things like type-graphql library.

Ref: https://github.com/wycats/javascript-decorators#object-literal-accessor-declaration

FYI https://github.com/tc39/proposal-decorators is the current decorator proposal.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

wmaurer picture wmaurer  路  3Comments

manekinekko picture manekinekko  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments