美文网首页前端开发
解决TypeScript装饰器(decorators)和Java

解决TypeScript装饰器(decorators)和Java

作者: kingller | 来源:发表于2019-07-23 16:31 被阅读13次

    Input Code

    function observable() {}
    
    class Example {
        @observable()
        toolbar = 'example';
    }
    
    export default Example;
    

    JavaScript output

    function observable() {}
    
    var Example = (_dec = observable(), (_class = (_temp = function Example() {
      (0, _classCallCheck2["default"])(this, Example);
      (0, _initializerDefineProperty2["default"])(this, "toolbar", _descriptor, this);
    }, _temp), (_descriptor = (0, _applyDecoratedDescriptor2["default"])(_class.prototype, "toolbar", [_dec], {
      configurable: true,
      enumerable: true,
      writable: true,
      initializer: function initializer() {
        return 'example';
      }
    })), _class));
    
    exports["default"] = Example;
    

    TypeScript output

    function observable() {}
    
    var Example = function Example() {
      (0, _classCallCheck2["default"])(this, Example);
      this.toolbar = 'example';
    };
    
    __decorate([observable(), __metadata("design:type", Object)], Example.prototype, "toolbar", void 0);
    
    exports["default"] = Example;
    

    我们发现两者编译出的装饰器属性代码并不相同。

    现在我们创建一个javascript类ExampleEnhance,继承typescript类Example,并重写装饰器属性toolbar

    // This is javascript code, but class Example is typescript
    class ExampleEnhance extends Example {
        @observable()
        toolbar = 'YY';
    }
    

    这时,我们期望toolbar的值为'YY',但是我们发现它的值仍然是'example'
    怎么办?
    我们有没有办法让TypeScriptJavaScript装饰器属性编译出来的代码相同呢?

    我们从TypeScript官方得到的回复是

    TypeScript's decorators currently work differently from ES decorators, hence the experimental flag. If you need ES decorators you'll need to continue to process the code with Babel.

    Because Typescript's decorator specification is not quite the same as anyone else's, they are always transformed.

    You cannot do this right now unless you remove Typescript from the chain entirely. It always transforms decorators, leaving nothing left for Babel to transform.

    因此,要让两者编译出相同的代码,我们必须要把typescript loader(比如awesome-typescript-loader, ts-loader)移除,而只使用babel来转换这两类代码。这里我们需要引入@babel/plugin-transform-typescript插件来处理TypeScript

    配置babel

    Install

    npm install @babel/plugin-transform-typescript
    

    babel.config.js

    module.exports = {
        presets: ['@babel/preset-typescript', '@babel/preset-react', '@babel/preset-env', 'mobx'],
        plugins: [
            ['@babel/plugin-transform-typescript', { allowNamespaces: true }],
            // ... other
        ]
    }
    

    webpack.config.js

    module.exports = {
        // ...
        resolve: {
            // Add '.ts' and '.tsx' as resolvable extensions.
            extensions: ['.js', '.ts', '.tsx']
        },
    
        module: {
            rules: [
                {
                    test: /\.tsx?$/,
                    loader: 'babel-loader',
                },
            ]
        }
    };
    

    那么,如果改成这样了,TypeScript的类型检测怎么办呢?不是相当于废了吗?
    你可以使用 TypeScript-Babel-Starterfork-ts-checker-webpack-plugin来启用TypeScript类型检测。

    我们这里来说明一下如何使用fork-ts-checker-webpack-plugin

    配置TypeScript类型检查器

    Install

    npm install fork-ts-checker-webpack-plugin fork-ts-checker-notifier-webpack-plugin
    

    webpack.config.js

    const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
    const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');
    
    module.exports = {
        // ...
        plugins: [
            new ForkTsCheckerWebpackPlugin({
                // 将async设为false,可以阻止Webpack的emit以等待类型检查器/linter,并向Webpack的编译添加错误。
                async: false
            }),
            // 将TypeScript类型检查错误以弹框提示
            // 如果fork-ts-checker-webpack-plugin的async为false时可以不用
            // 否则建议使用,以方便发现错误
            new ForkTsCheckerNotifierWebpackPlugin({
                title: 'TypeScript',
                excludeWarnings: true,
                skipSuccessful: true,
            }),
        ]
    };
    

    相关文章

      网友评论

        本文标题:解决TypeScript装饰器(decorators)和Java

        本文链接:https://www.haomeiwen.com/subject/ibaolctx.html