概述
Typescript會根據配置文件來設定編譯編譯方式和細節,這篇文章來講講Typescript編譯配置文件常用的選項的含義。它的編譯選項非常多,更多內容可參考官方文檔Intro to the TSConfig Reference。
對於初學者而言,不需要一開始就掌握這一部分內容,可以選擇先跳過本章節。
配置
按照功能,配置可以分爲9類:
- 文件
- 項目
- 約束
- 模塊解析
- 代碼映射
- 風格檢查
- 命令行
- 觀察
- 高級
其中後8類屬性編寫在compilerOptions
對象中。
文件
files
類型:數組。
控制需要進行編譯的文件路徑,可以省略後綴名ts。
示例:
{
"files": ["src/a.ts"]
}
include
類型:數組。
控制需要進行編譯的文件路徑,與files不同的是可以使用通配符*
(表示文件)、**
(比較目錄)和?
(表示字符)。
示例:
{
"include": ["src/**/*"]
}
表示編輯src目錄下的所有ts文件。
如果沒有配置include,則編譯工作目錄下的所有ts文件,相當於設置爲["**/*"]
。
exclude
類型:數組。默認值爲:["node_modules", "bower_components", "jspm_packages"]
和配置outDir指定的文件夾。
用於排除不需要編譯的文件,可以使用與include相同的通配符。
exclude只是對include的修飾,如果一個文件處在files列表、被import
語句導入、被/// <reference>
語句指定或是類型文件的,exclude配置無法將其排除。
extends
類型:字符串。
值含義是另一個配置文件的路徑,本配置文件會在繼承被引入的配置文件的基礎上融合。files、include、exclude直接覆蓋,references無法繼承。
項目
target
類型:字符串。默認:ES3
。
控制生成的js文件所使用的ES版本。可選值可參考:tsconfig#target,其中ESNEXT
是個比較特殊的值,它表示使用當前Typescript版本支持的最新的ES版本。
lib
類型:字符串數組。
不同的Javascript運行環境和ES版本有不同API,lib控制哪些API可以被使用,本質上是引入相對應的類型聲明文件。
target選項會影響lib的默認值,對應目標環境的API會被自動引入。
示例:
{
"compilerOptions": {
"lib": ["ES2015", "DOM"]
}
}
這樣配置之後,在代碼中就可以使用ES2015和DOM中的API。
更多可配置的選項可見:tsconfig#lib
module
類型:字符串。
控制編譯結果的模塊系統,常用的有:CommonJS
和ES6
。
target選項會影響module的默認值。
outDir
類型:布爾。默認:false
。
默認情況下,生成的文件(包括js文件、d.ts文件和代碼映射文件)與ts源文件在同一目錄下。設置了outDir後,輸出文件被轉移至對應目錄,且目錄結構仍然保留。輸出目錄中的第一層目錄有選項rootDir控制。
rootDir
類型:字符串。
當設置了outDir,控制輸出文件目錄結構的根目錄。默認值是所有非聲明文件的ts文件的最長公共路徑。
比如,如果源代碼目錄結構是這樣的,設置了"outDir": "out"
:
Workspace
├── tsconfig.json
├── src
│ ├── a.ts
│ ├── b.ts
│ ├── sub
│ │ ├── c.ts
├── types.d.ts
那麼輸出結構爲。
Workspace
├── out
│ ├── a.js
│ ├── b.js
│ ├── sub
│ │ ├── c.js
如果設置了rootDir,那麼輸出文件夾中的第一層目錄就是指定的目錄。比如設置"outDir": "./"
,那麼輸出結構爲。
Workspace
├── out
│ ├── src
│ │ ├── a.js
│ │ ├── b.js
│ │ ├── sub
│ │ │ ├── c.js
outFile
類型:布爾。默認:false
。
設置一個文件路徑,將所有代碼打包到一個文件內。
要求module設置爲System
或AMD
。
noEmit
類型:布爾。默認:false
。
設置爲true
後不會產生輸出文件,結果值保存在內容中,通常在其它編譯工具(入Babel)中使用。
declaration
類型:布爾。默認:false
。
自動生成聲明文件(.d.ts)。
sourceMap
類型:布爾。默認:false
。
生成代碼映射文件。
importHelpers
類型:布爾。默認:false
。
在運行時引入輔助庫。
Typescript在編譯模塊文件中的新語法爲舊語法(比如從ES6到ES5)時,需要引入一些輔助函數。默認情況下,這些輔助函數被硬編碼到使用處。爲了壓縮代碼,開啓importHelpers會使得輔助函數在運行時被引用,這樣可以減少代碼量。
示例:
export function copy(arg: string[]) {
return [...arg]
}
這個ts文件中使用了ES6的擴展運算符。當不使用importHelpers時,被編譯成:
"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
exports.__esModule = true;
exports.copy = void 0;
function copy(arg) {
return __spreadArrays(arg);
}
exports.copy = copy;
如果開啓了importHelpers
,被編譯成:
"use strict";
exports.__esModule = true;
exports.copy = void 0;
var tslib_1 = require("tslib");
function copy(arg) {
return tslib_1.__spreadArrays(arg);
}
exports.copy = copy;
注意:使用此功能時,編譯時和運行時環境都需要tslib庫(NPM安裝)。
allowJs
類型:布爾。默認:false
。
允許在ts文件中引入js文件。
checkJs
類型:布爾。默認:false
。
檢查在ts文件中引入的js文件的語法。
removeComments
類型:布爾。默認:false
。
刪除註釋。
約束
strict
類型:布爾。默認:false
。
代碼檢查時遵循嚴格模式,同時開啓:
- alwaysStrict
- strictNullChecks
- strictBindCallApply
- strictFunctionTypes
- strictPropertyInitialization
- noImplicitAny
- noImplicitThis
alwaysStrict
類型:布爾。默認:false
。
使用嚴格模式編譯ts文件,在生成的js文件中使用'use strict'
。
onImplicitAny
類型:布爾。默認:false
。
禁止使用不明確的any
類型。
示例:
function slice(arg) {
return arg.slice(0, 1)
}
這一段代碼中,由於沒有聲明參數arg
的類型,編譯器推測arg
爲any
類型。如果設置了"noImplicit": true
,那就會報錯,必須顯示聲明爲any
類型,即:function slice(arg: any)
。
onImplicitThis
類型:布爾。默認:false
。
禁止this
具有不明確的類型。
這種情況通常發生在高等函數中,比如:
class GetLog {
get() {
return function log () {
console.log(this)
}
}
}
log
函數不是GetLog
類的對象,而是由GetLog
類方法生成的函數,其this指向並不是GetLog
類的實例,而是全局對象或undefined
,可能會違背這個函數的設計目的。
strictBindCallApply
類型:布爾。默認:false
。
限制函數的call
,apply
和bind
方法的傳參爲函數的參數類型。
示例:
function parse(arg: string) {
return parseInt(arg)
}
parse.call(undefined, true)
因爲true
不是string
類型值,所以編譯器報錯提示類型錯誤。
如果沒有開啓這個選項,那麼編譯器不會報錯,且call
,apply
和bind
方法的返回值爲any
類型。
strictFunctionTypes
類型:布爾。默認:false
。
嚴格的函數類型檢查。
在未開啓這個選項時,編譯器會包容一些可能發生的聯合類型錯誤,將錯誤的報告延遲到運行時。
示例:
function log(arg: string) {
console.log(arg.toLowerCase())
}
type StringOrNumberFunc = (arg: string | number) => void
let f: StringOrNumberFunc = log
f(1)
由於log
只接受字符串類型的參數,但是f
可以接受字符串或數字的參數,所以兩者之間的參數類型沒有完全匹配,如果將數字傳入f
函數就會報錯。
設置了"strictFunctionTypes": true
後可以避免這個問題,在編譯階段編譯器會報告這一可能發生的錯誤。
注意:這一特性僅適用於function
函數,不適用對象或類方法。
strictNullChecks
類型:布爾。默認:false
。
嚴格檢查null
和undefined
。
在未開啓這個選項時,null
和undefined
可以被其它類型的變量兼容,進而在運行時可能出錯。
示例:
let array = []
let target = array.find(a => a.name === 'a')
console.log(target.name)
array
是空數組,target
必定爲undefined
,所以在執行target.name
時會報錯。
如果設置了"strictNullChecks": true
,這一問題在編譯階段會被報告出來。
strictPropertyInitialization
類型:布爾。默認:false
。
禁止在class
聲明中,類屬性被聲明但是沒有被初始化(聲明初始化或構造函數初始化)。
模塊解析
baseUrl
類型:字符串。
引入非絕對地址模塊的基地址。
moduleResolution
類型:字符串。
控制模塊的搜索策略,即對於引入ts的其它ts文件或模塊,編譯其如何找到其源文件。
可選值有node
和classic
,其中classic
主要用於向後兼容,一般常用node
。
可多細節可查看module-resolution。
esModuleInterop
類型:布爾。默認:false
。
輔助解決ES模塊中引入CommonJs模塊時的問題,主要針對ESM中有默認導出而CommonJs沒有。
開啓後allowSyntheticDefaultImports會被默認開啓。
更多細節可查看tsconfig#esModuleInterop。
allowSyntheticDefaultImports
類型:布爾。默認:false
。
將全部導出轉換爲默認導出。
如果一個模塊,沒有默認導出,那我們需要已這樣的方式引入全部變量:
import * as _ from 'lodash'
設置了"allowSyntheticDefaultImports": true
後,我們可以以默認導出的方式引入模塊:
import _ from 'lodash'
paths
類型:對象。
控制模塊路徑的重映射,也可以理解爲路徑別名。
示例:
{
"compilerOptions": {
"baseUrl": "."
"paths": {
"@/*":["src/*"],
"jquery": ["node_modules/jquery/dist/jquery"]
}
}
}
在這個例子中,一個條配置使得無論當前編寫的文件在目錄結構中的什麼位置,或是與src中目標文件的相對關係如何,都可以直接使用@
前綴且相對於baseUrl的路徑來訪問;第二條配置,顯示的設置了jquery的位置。
使用這個選項前必須設置baseUrl。