TypeScript 的學習資料很是多,其中也不乏不少優秀的文章和教程。可是目前爲止沒有一個我特別滿意的。緣由有:前端
所以個人想法是作一套不一樣市面上大多數的 TypeScript 學習教程。以人類認知的角度思考問題,學習 TypeScript,經過通俗易懂的例子和圖片來幫助你們創建 TypeScript 世界觀。node
系列安排:react
目錄未來可能會有所調整。
注意,個人系列文章基本不會講 API,所以須要你有必定的 TypeScript 使用基礎,推薦兩個學習資料。git
結合這兩個資料和個人系列教程,掌握 TypeScript 指日可待。es6
接下來,咱們經過幾個方面來從宏觀的角度來看一下 TypeScript。github
<!-- more -->typescript
這篇文章是個人 TypeScript 系列的第 5 篇。今天咱們就來看下, TypeScript 的配置文件 tsconfig.json 該如何寫。json
和 package.json 同樣, 它也是一個 JSON 文件。package.json 是包描述文件,對應的 Commonjs 規範,而 tsconfig.json 是最終被 TypeScript Compiler 解析和使用的一個 JSON 文件。 TypeScript Compiler 用這個配置文件來決定如何對項目進行編譯。bash
說到編譯,不得不提一個知名選手 - babel。 和 TypeScript 相似, 他們均可以將一種語法靜態編譯成另一種語法。若是說我想編譯一個文件,我只須要告訴 babel 個人文件路徑便可。babel
npx babel script.js
有時候我想編譯整個文件夾:
npx babel src --out-dir lib
babel 也能夠指定輸出目錄,指定須要忽略的文件或目錄等等, TypeScript 也是同樣!你固然能夠像 babel 同樣在命令行中所有指定好,也能夠將這些配置放到 tsconfig.json 中,以配置文件的形式傳遞給 TypeScript Compiler 。 這就是 tsconfig.json 文件的初衷,即接受用戶輸入做爲配置項。
咱們先來看一個簡單的 tsconfig 文件。
{ "compilerOptions": { "outDir": "./built", "allowJs": true, "target": "es5" }, "include": ["./src/**/*"] }
如上配置作了:
實際項目有比這個更復雜。 接下來, 咱們來進一步解讀。 不過在講配置項以前,咱們先來看下 tsconfig.json 是如何被解析的。
若是一個目錄下存在一個 tsconfig.json 文件,那麼意味着這個目錄是 TypeScript 項目的根目錄。 若是你使用 tsc 編譯你的項目,而且沒有顯式地指定配置文件的路徑,那麼 tsc 則會逐級向上搜索父目錄尋找 tsconfig.json ,這個過程相似 node 的模塊查找機制。
如圖:
我在 上帝視角看 TypeScript 一種講述了 TypeScript 究竟作了什麼,帶你從宏觀的角度看了一下 TypeScript。 其中提到了 TypeScript 編譯器會接受文件或者文件集合做爲輸入,最終轉換爲 JavaScript(noEmit 爲 false) 和 .d.ts(declarations 爲 true)。
這裏其實還少了一個點,那就是除了接受文件或者文件集合做爲輸入,還會接受 tsconfig.json。tsconfig.json 的內容決定了編譯的範圍和行爲,不一樣的 配置可能會獲得不一樣的輸出,或者獲得不一樣的檢查結果。
當 tsc 找到了一個 tsconfig.json 文件,那麼其規定的編譯目錄則所有會被 typescript 處理,固然也包括其依賴的文件。 若是 tsc 沒有找到一個 tsconfig.json 或 tsconfig 沒有有效信息,那麼 tsc 會使用默認配置。 好比 tsconfig 是一個空的就沒有有效信息:
{}
tsconfig 的所有屬性,以及屬性的默認值能夠在這裏找到: http://json.schemastore.org/t...
總結一下 tsc 解析 tsconfig.json 的邏輯。
若是命令行指定了配置選項或者指定了配置文件的路徑,那麼直接會讀取。
根據 tsconfig json schema 校驗是否格式正確。
不然,會從當前目錄查找 tsconfig.json 文件, 若是找不到則逐層向上搜索父目錄。
若是找到了則會去根據 tsconfig json schema 校驗是否格式正確。
tsconfig 的頂層屬性(Top Level)很少,主要有:compilerOptions, files, include, exclude,extends,compileOnSave等。
{ "extends": "@tsconfig/node12/tsconfig.json", "compilerOptions": {}, "include": ["src/**/*"], "exclude": ["node_modules"] }
除了 compilerOptions,其餘也相對比較好理解。 所以接下來我只針對 compilerOptions 詳細講解一番。
詳細全面的內容,你們只須要參考官網的就行了。官網寫的不只全面,並且作了分類,很是清晰。
接下來,我會根據功能分開講幾個經常使用 的配置。
經常使用的是如下四個,因爲前面已經作了介紹,所以就不贅述了。
默認:false
首次發佈版本:2.1
這個是和 ECMAScript 規範相關的,工做機制和 ES 5 的嚴格模式同樣, 而且輸出的 JS 頂部也會也會帶上 'use strict'。
默認:true
首次發佈版本:-
我在 - TypeScript 類型系統 中提到了若是不對變量顯式聲明類型,那麼 TypeScript 會對變量進行類型推導,這固然也有推導不出的狀況,這個時候該變量的類型就是 any,這個叫作隱式 any。區別於顯式 any:
const a: any = {};
隱式 any 是 TypeScript 編譯器推斷的。
默認:true
首次發佈版本:2.0
和隱式 any 類型, 只不過此次是針對的特殊的一個關鍵字 this,也就是你須要顯式地指定 this 的類型。
默認:true
首次發佈版本:2.3
實際上 strict 只是一個簡寫,是多個規則的合集。 相似於 babel 中插件(plugins)和 預設(presets)的差異。換句話說若是你指定了 strict 爲 true ,那麼全部嚴格相關的規則的都會開啓,我所講的嚴格檢查都是,還有一部分我沒有提到的。另外未來若是增長更多嚴格規則,你只要開啓了 strict 則會自動加進來。
目的:allowSyntheticDefaultImports,allowUmdGlobalAccess,esModuleInterop,moduleResolution 都是爲了和其餘模塊化規範兼容作的。
還有一個配置 module,規定了項目的模塊化方式,選項有 AMD,UMD,commonjs 等。
目的: baseUrl,paths,rootDirs, typeRoots,types 都是爲了簡化路徑的拼寫作的。
這個配置是告訴 TypeScript 如何解析模塊路徑的。好比:
import { helloWorld } from "hello/world"; console.log(helloWorld);
這個就會從 baseUrl 下找 hello 目錄下的 world 文件。
定義相似別名的存在,從而簡化路徑的書寫。
注意是 rootDirs ,而不是 rootDir,也就是說根目錄能夠有多個。 當你指定了多個根目錄的時候, 不一樣根目錄的文件能夠像在一個目錄下同樣互相訪問。
實際上也有一個叫 rootDir 的, 和 rootDirs 的區別就是其只能指定一個。
types 和 typeRoots 我在 - types 和 @types 是什麼? 已經講得很清楚了,這裏就很少說了。
默認:false
首次發佈版本:1.8
顧名思義,容許在 TypeScript 項目中使用 JavaScript,這在從 JavaScript 遷移到 TypeScript 中是很是重要的。
默認:false
首次發佈版本:-
和 allowJs 相似, 只不過 checkJs 會額外對 JS 文件進行校驗。
若是 TypeScript 是將 TS 文件編譯爲 JS,那麼聲明文件 + JS 文件就能夠反推出 TS 文件。
這兩個用來生成 .d.ts 和 .d.ts 的 sourcemap 文件。
默認:false
首次發佈版本:1.0
默認:false
首次發佈版本:2.9
默認:react
首次發佈版本:2.2
這個是告訴 TypeScript 如何編譯 jsx 語法的。
默認:-
首次發佈版本:2.0
lib 我在 TypeScript 類型系統 中講過。 Typescript 提供了諸如 lib.d.ts 等類型庫文件。隨着 ES 的不斷更新, JavaScript 類型和全局變量會逐漸變多。Typescript 也是採用這種 lib 的方式來解決的。
(TypeScript 提供的部分 lib)
outDir 和 outFile 這兩個配置則是告訴 TypeScript 將文件生成到哪裏。
默認:和 ts 文件同目錄(且同名,只是後綴不一樣)
首次發佈版本:-
默認:-
首次發佈版本:1.0
module 是 CommonJS 和 ES6 module 不能知道 outFile,只有是 None, System 或 AMD 才行,其會將這些模塊的文件內容打包到全局文件內容以後。
而 noEmit 則是控制是否輸出 JS 文件的。
默認:false
首次發佈版本:-
若是你只但願用 TypeScript 進行類型檢查,不但願要它生成文件,則能夠將 noEmit 設置成 true。
即輸出的 JavaScript 對標的 ECMA 規範。 好比 「target」: 「es6」 就是將 es6 + 的語法轉換爲 ES6 的 代碼。其選項有 ES3,ES5,ES6 等。
爲何沒有 ES4 ? ^_^
你們也能夠關注個人公衆號《腦洞前端》獲取更多更新鮮的前端硬核文章,帶你認識你不知道的前端。
知乎專欄【 Lucifer - 知乎】
點關注,不迷路!