[TOC]
目前轉換 Typescript 有三種常用的方式:
1. 經典的`ts-loader`
2. `awesome-typescript-loader`
3. `babel7`之后已經支持的`@babel/preset-typescript`
> Xee:在其他react handbook書中“開發環境配置” 中可能介紹過~
> [Use TypeScript to Create a Secure API with Node.js and Express: Getting Started](https://auth0.com/blog/use-typescript-to-create-a-secure-api-with-nodejs-and-express-getting-started/)
# 用 Babel 去構建 TypeScript 項目
## Babel 編譯 TS
現在空項目中創建 package.json 文件,再去安裝 Babel,@babel/core 是 babel 的核心,@babel/cli 是 Babel 的命令行,可以在終端使用 Babel 的命令行,輸入 `npx babel --help` 查看所有的命令。接下來創建 src 目錄并進入:
~~~shell
npm init -y && npm install -D @babel/core @babel/cli && mkdir src
npm install -D @babel/preset-env @babel/preset-typescript
npm install -D @babel/plugin-proposal-class-properties
npm install -D @babel/plugin-proposal-object-rest-spread @babel/plugin-proposal-decorators
~~~
`package.json` 同級目錄下新建.`babelrc`文件
```json
{
"presets": [
"@babel/preset-env",
"@babel/preset-typescript" // presets是自下而上執行的
],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": true }]
]
}
```
> 使用的時候注意下面兩點:
> 1.If you are including your plugins manually and using @babel/plugin-proposal-class-properties, make sure that @babel/plugin-proposal-decorators comes before @babel/plugin-proposal-class-properties.
> 2. When using the legacy: true mode, @babel/plugin-proposal-class-properties must be used in loose mode to support the @babel/plugin-proposal-decorators.
這時在 package.json 文件的`scripts`里面新增以下內容:
```
"scripts": {
"build": "npx babel src -d dist -x \".ts, .tsx\"",
"dist": "npx babel src --out-dir dist --extensions '.ts , .tsx'"
},
```
build 是 dist 的簡寫版本,功能是一樣的,Babel 不能自己識別`.tsx和.ts`文件,所以需要`--extensions`指定文件,簡寫為`-x`。
現在來配置,安裝 typescript:
~~~shell
npm install -D typescript
~~~
初始化配置文件:
~~~shell
npx tsc --init
~~~
打開配置文件 `tsconfig.json`,更改 `noEmit` 配置項,表示只執行類型檢查不編譯輸出文件:
~~~shell
"noEmit": true, /* Do not emit outputs. */
~~~
這時在命令行執行,持續監聽文件的更改就行了:
~~~shell
npx tsc --watch
~~~
類型檢查配置完成。這時 Babel 負責編譯,typescript 負責類型檢查。
## babel 環境 TS 兼容問題
Babel 環境中 TypeScript 中的語法有四個不能使用:
* 命名空間 `namespace`
* 模塊兼容 `export = xx`
* 類型斷言只支持 `as`方式
* 常量枚舉 `const enmu {}`
現在還是推薦使用主流方式去構建 TypeScript 項目,即 webpack 的方式,使用 ts-loader 配合 typescript 實現。附贈一個技巧:
> webpack 使用 ts-loader來編譯檢查 TypeScript 的時候,隨著項目越來越大,速度會變慢這時需要
> 我們配置 `options:{ transpileOnly:true }`表示 `ts-loader`只做編譯不做類型檢查
> 這時類型檢查可以交給插件`fork-ts-checker-webpack-plugin`
> **各司其職的好處就可以提高文件的編譯速度**
>**請務必牢記 Babel 不做類型檢查,如果需要類型檢查安裝 TypeScript 來執行類型檢查的工作。**
> [用 Babel 去構建 TypeScript 項目](https://www.jianshu.com/p/83c14c881a2c)
# Using ES6 and ESNext with TypeScript
有時候你需要使用 `Promise` 或者 `document` 這些在 ES6 或者 操作 DOM 時,需要用到的屬性時,typescript 可能會報錯,不能找到相關的定義!
可以通過在 `tsconfig.json`中進行配置解決該問題:
```json
{
"compilerOptions": {
"target": "es5",
"outDir": "lib",
"lib": [
"dom",
"es2017"
]
},
"include": [
"src"
]
}
```
添加 `lib` 屬性,值為包含 "es2017" 或者 "es6" 的 數組,可以解決相關問題(或者其他在ES5 中不存在的定義)
或者你可以借助 polyfill,它們已經實現了相關定義:
安裝:
```js
npm i -D core-js
```
在代碼中 進行導入:
```js
// import 'shim' from 'core-js':
import "core-js/shim";
const foo = () => Promise.resolve(null);
```
# TypeScript Node
https://github.com/TypeStrong/ts-node
通過node 直接運行ts文件!
~~~
yarn global add ts-node
# Install a TypeScript compiler (requires `typescript` by default).
yarn global add typescript
~~~