Input Codejavascript
function observable() {}
class Example {
@observable()
toolbar = 'example';
}
export default Example;
複製代碼
JavaScript outputhtml
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 outputjava
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;
複製代碼
咱們發現二者編譯出的裝飾器屬性代碼並不相同。react
如今咱們建立一個javascript類ExampleEnhance
,繼承typescript類Example
,並重寫裝飾器屬性toolbar
。webpack
// This is javascript code, but class Example is typescript
class ExampleEnhance extends Example {
@observable()
toolbar = 'YY';
}
複製代碼
這時,咱們指望toolbar
的值爲'YY'
,可是咱們發現它的值仍然是'example'
。 怎麼辦? 咱們有沒有辦法讓TypeScript
和JavaScript
裝飾器屬性編譯出來的代碼相同呢?git
咱們從TypeScript官方獲得的回覆是github
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.web
Because Typescript's decorator specification is not quite the same as anyone else's, they are always transformed.typescript
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.npm
所以,要讓二者編譯出相同的代碼,咱們必需要把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-Starter 或 fork-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,
}),
]
};
複製代碼