理解 Typescript 配置文件

熟悉 Typescript 配置選項是 TS 項目開發的最基本要求。
TS 使用 tsconfig.json 做爲其配置文件,它主要包含兩塊內容:html

  1. 指定待編譯的文件
  2. 定義編譯選項

另外,通常來講,tsconfig.json 文件所處的路徑就是當前 TS 項目的根路徑node

基本用法

TS 的編譯命令爲 tsc ,當咱們在命令行中直接輸入 tsc 時,會打印出以下的使用說明:es6

$ tsc
Version 2.7.2
Syntax:   tsc [options] [file ...]
Examples: tsc hello.ts
          tsc --outFile file.js file.ts
          tsc @args.txt

Options:
-h, --help                                         Print this message.
--all                                              Show all compiler options.
-v, --version                                      Print the compiler's version.
...

若是僅僅是編譯少許的文件,咱們能夠直接使用 tsc ,經過其選項來設置編譯配置,如:typescript

tsc --outFile file.js --target es3 --module commonjs file.ts

但若是是編譯整個項目的話,最推薦的作法是使用 tsconfig.json 文件,這樣就不用每次編譯時都還得手動敲配置,並且也便於團隊協做。express

如下是讓 tsc 使用 tsconfig.json 的兩種方式:npm

  • 不顯式指定 tsconfig.json ,此時,編譯器會從當前路徑開始尋找 tsconfig.json 文件,若是沒有找到,則繼續往上級路徑逐步尋找,直到找到爲止
  • 經過 --project (或縮寫 -p )指定一個包含 tsconfig.json 的路徑,或者包含配置信息的 .json 文件路徑

注意,tsc 的命令行選項具備優先級,會覆蓋 tsconfig.json 中的同名選項。json

使用示例

下面是一個簡單的配置示例:數組

{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true
  },
  "files": [
    "app.ts",
    "foo.ts",
  ]
}

其中,compilerOptions 用來配置編譯選項,files 用來指定待編譯文件。
這裏的待編譯文件是指入口文件,任何被入口文件依賴的文件,好比 foo.ts 依賴 bar.ts ,那這裏並不須要寫上 bar.ts ,編譯器會自動把全部的依賴文件納爲編譯對象。bash

也可使用 includeexclude 來指定和排除待編譯文件:app

{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

因此,總結一下,指定待編譯文件有兩種方式:

  • 使用 files 屬性
  • 使用 includeexclude 屬性

開發者能夠按照本身的喜愛使用其中任意一種。但它們不是互斥的,在某些狀況下二者搭配起來使用效果更佳。

配置說明

文件指定

files 屬性是一個數組,數組元素能夠是相對文件路徑和絕對文件路徑。

includeexclude 屬性也是一個數組,但數組元素是相似 glob 的文件模式。它支持的 glob 通配符包括:

  • * :匹配 0 或多個字符(注意:不含路徑分隔符)
  • ? :匹配任意單個字符(注意:不含路徑分隔符)
  • **/ :遞歸匹配任何子路徑

在繼續說明以前,有必要先了解下在編譯器眼裏什麼樣的文件纔算是 TS 文件
TS 文件指拓展名爲 .ts.tsx.d.ts 的文件。若是開啓了 allowJs 選項,那 .js.jsx 文件也屬於 TS 文件。

若是僅僅包含一個 * 或者 .* ,那麼只有TS 文件纔會被包含。

若是 filesinclude 都未設置,那麼除了 exclude 排除的文件,編譯器會默認包含路徑下的全部 TS 文件

若是同時設置 filesinclude ,那麼編譯器會把二者指定的文件都引入。

若是未設置 exclude ,那其默認值爲 node_modulesbower_componentsjspm_packages 和編譯選項 outDir 指定的路徑。

exclude 只對 include 有效,對 files 無效。即 files 指定的文件若是同時被 exclude 排除,那麼該文件仍然會被編譯器引入。

前面提到,任何被 filesinclude 引入的文件的依賴會被自動引入。
反過來,若是 B.tsA.ts 依賴,那麼 B.ts 不能被 exclude 排除,除非 A.ts 也被排除了。

有一點要注意的是,編譯器不會引入疑似爲輸出的文件。好比,若是引入的文件中包含 index.ts ,那麼 index.d.tsindex.js 就會被排除。一般來講,只有拓展名不同的文件命名法是不推薦的。

tsconfig.json 也能夠爲空文件,這種狀況下會使用默認的編譯選項來編譯全部默認引入的文件。

編譯選項

經常使用選項

選項字段 類型 默認值 說明
allowJs boolean false 容許編譯 JS 文件
checkJs boolean false 報告 JS 文件中存在的類型錯誤須要配合 allowJs 使用
declaration boolean false 生成對應的 .d.ts 文件
declarationDir string - 生成的 .d.ts 文件存放路徑默認與 .ts 文件相同
experimentalDecorators boolean false 啓用實驗功能-ES 裝飾器
jsx string Preserve .tsx 中支持 JSX :ReactPreserve詳細說明
jsxFactory string React.createElement jsx 設置爲 React 時使用的建立函數
lib string[] - 編譯時引入的 ES 功能庫,包括:es5es6es7dom 等。若是未設置,則默認爲: targetes5 時: ["dom", "es5", "scripthost"] targetes6 時: ["dom", "es6", "dom.iterable", "scripthost"]
module string target === "es3" or "es5" ?"commonjs" : "es6" 生成的模塊形式:nonecommonjsamdsystemumdes6es2015esnext 只有 amdsystem 能和 outFile 一塊兒使用 targetes5 或更低時可用 es6es2015
moduleResolution string module === "amd" or "system" or "es6" ? "classic" : "node" 模塊解析方式,詳細說明
noImplicitAny boolean false 存在隱式 any 時拋錯
noImplicitReturns boolean false 不存在 return 時拋錯
noImplicitThis boolean false this 可能爲 any 時拋錯
outDir string - 編譯生成的文件存放路徑默認與 .ts 文件相同
sourceMap boolean false 生成 .map 文件
target string es3 生成 .js 文件版本
附: 官方完整的編譯選項列表

類型相關

類型相關的選項包括 typeRootstypes

有一個廣泛的誤解,覺得這兩個選項適用於全部的類型聲明文件,包括用戶自定義的聲明文件。其實否則。
這兩個選項只對經過 npm 安裝的聲明模塊有效,用戶自定義的類型聲明文件與它們沒有任何關係

聲明模塊一般會包含一個 index.d.ts 文件,或者其 package.json 設置了 types 字段。

默認的,全部位於 node_modules/@types 路徑下的模塊都會引入到編譯器。
具體來講是,./node_modules/@types../node_modules/@types../../node_modules/@types 等等。

typeRoots 用來指定默認的類型聲明文件查找路徑,默認爲 node_modules/@types 。好比:

{
  "compilerOptions": {
    "typeRoots": ["./typings"]
  }
}

上面的配置會自動引入 ./typings 下的全部 TS 類型聲明模塊,而不是 ./node_modules/@types 下的模塊。

若是不但願自動引入 typeRoots 指定路徑下的全部聲明模塊,那可使用 types 指定自動引入哪些模塊。好比:

{
  "compilerOptions": {
    "types" : ["node", "lodash", "express"]
  }
}

只會引入 nodelodashexpress 三個聲明模塊,其它的聲明模塊則不會被自動引入。
若是 types 被設置爲 [] ,那麼將不會自動引入任何聲明模塊。此時,若是想使用聲明模塊,只能在代碼中手動引入了。

請記住,自動引入只對包含全局聲明的模塊有效。好比 jQuery ,咱們不用手動 import 或者 ///<reference/> 便可在任何文件中使用 $ 的類型。再好比,對於 import 'foo' ,編譯器會分別在 node_modulesnode_modules/@types 文件下查找 foo 模塊和聲明模塊。

基於此,若是想讓自定義聲明的類型不須要手動引入就能夠在任何地方使用,能夠將其聲明爲全局聲明 global ,而後讓 files 或者 include 包含便可。
好比:

declare global {
  const graphql: (query: TemplateStringsArray) => void;
  namespace Gatsby {
    interface ComponentProps {
      children: () => React.ReactNode,
      data: RootQueryType
    }
  }
}

這樣的話,就能夠在任何地方直接使用 graphqlGatsby 對應的類型了。

配置複用

可使用 extends 來實現配置複用,即一個配置文件能夠繼承另外一個文件的配置屬性。

好比,創建一個基礎的配置文件 configs/base.json

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

而後,tsconfig.json 就能夠引用這個文件的配置了:

{
  "extends": "./configs/base",
  "files": [
    "main.ts",
    "supplemental.ts"
  ]
}

這種繼承有兩種特色:

  • 繼承者中的同名配置會覆蓋被繼承者
  • 全部相對路徑都被解析爲其所在文件的路徑

參考資料

相關文章
相關標籤/搜索