s-panferov / awesome-typescript-loader

Awesome TypeScript loader for webpack
Other
2.35k stars 179 forks source link

How to make the compiled decorator code not different from typescript and babel? #637

Closed kingller closed 5 years ago

kingller commented 5 years ago

Hi, I find the decorator code compiled in TypeScript and javascript are different. Input Code

class Toolbar {
    @observable
    toolbar = 'XX';
}

The decorator code in TypeScript compiled to

var Toolbar = function Toolbar(toolbar, option) {
  var _this = this;
  (0, _classCallCheck2["default"])(this, Toolbar);
  this.toolbar = 'XX';  // here is different
};

__decorate([mobx_1.observable, __metadata("design:type", Object)], Toolbar.prototype, "toolbar", void 0);

but when not use TypeScript, the decorator code compiled to

function TableExampleStore() {
    // ...
    (0, _initializerDefineProperty2["default"])(_this, "toolbar", _descriptor, (0, _assertThisInitialized2["default"])(_this));
    return _this;
  }
  // ...
  (_descriptor = (0, _applyDecoratedDescriptor2["default"])(_class.prototype, "toolbar", [_mobx.observable], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function initializer() {
    var _this2 = this;

    return 'XX'; // here is different
  }
})

I find it use toolbar='XX' when compile the typescript code, but use initializer when compile the javascript code by babel. When I create a javascript class extends a typescript class, and overwrite a decorator field as bellow, the initializer value is lost.

// This is javascript code, but class Toolbar is typescript
class TableExampleStore extends Toolbar {
    @observable
    toolbar = 'YY';
}

How can I make them compile to the same code?

Here is my tsconfig.json file

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "strictNullChecks": false,
        "module": "commonjs",
        "target": "ESNext",
        "jsx": "react",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "moduleResolution": "node",
        "allowJs": true,
        "baseUrl": "."
    },
    "include": [
        "./src/**/*"
    ]
}

Can you help me please? Thanks.