嚴格函式型別
TypeScript 2.6 引入了一個新的嚴格檢查標誌 strictFunctionTypes。strictFunctionTypes 開關屬於 strict 系列開關的一部分,這意味著在 strict 模式下它預設開啟。你可以透過在命令列或 tsconfig.json 中設定 --strictFunctionTypes false 來關閉它。
在 strictFunctionTypes 下,函式型別引數位置會被逆變(contravariantly)檢查,而不是雙變(bivariantly)。有關函式型別方差的背景知識,請檢視 什麼是協變與逆變?。
更嚴格的檢查適用於所有函式型別,但方法或建構函式宣告中的函式型別除外。排除方法主要是為了確保泛型類和介面(例如 Array<T>)繼續保持大部分協變關係。
考慮以下示例,其中 Animal 是 Dog 和 Cat 的超型別:
tsdeclare let f1: (x: Animal) => void;declare let f2: (x: Dog) => void;declare let f3: (x: Cat) => void;f1 = f2; // Error with --strictFunctionTypesf2 = f1; // Okf2 = f3; // Error
第一個賦值在預設型別檢查模式下是被允許的,但在嚴格函式型別模式下會被標記為錯誤。直觀地講,預設模式允許這種賦值,因為它可能是合理的,而嚴格函式型別模式將其視為錯誤,因為它無法證明是合理的。無論哪種模式,第三個賦值都是錯誤,因為它絕對不合理。
用另一種方式描述該示例:在預設型別檢查模式下,型別 (x: T) => void 對於 T 是雙變的(即協變或逆變),但在嚴格函式型別模式下,它對於 T 是逆變的。
示例
tsinterface Comparer<T> {compare: (a: T, b: T) => number;}declare let animalComparer: Comparer<Animal>;declare let dogComparer: Comparer<Dog>;animalComparer = dogComparer; // ErrordogComparer = animalComparer; // Ok
第一個賦值現在變成了錯誤。實際上,T 在 Comparer<T> 中是逆變的,因為它僅用於函式型別引數位置。
順便提一下,請注意,雖然某些語言(如 C# 和 Scala)要求方差註解(out/in 或 +/-),但由於 TypeScript 的結構化型別系統,方差是自然從泛型型別內型別引數的實際使用中湧現出來的。
注意
在 strictFunctionTypes 下,如果 compare 被宣告為方法,則第一個賦值仍然被允許。實際上,T 在 Comparer<T> 中是雙變的,因為它僅用於方法引數位置。
tsinterface Comparer<T> {compare(a: T, b: T): number;}declare let animalComparer: Comparer<Animal>;declare let dogComparer: Comparer<Dog>;animalComparer = dogComparer; // Ok because of bivariancedogComparer = animalComparer; // Ok
TypeScript 2.6 還改進了涉及逆變位置的型別推斷:
tsfunction combine<T>(...funcs: ((x: T) => void)[]): (x: T) => void {return x => {for (const f of funcs) f(x);};}function animalFunc(x: Animal) {}function dogFunc(x: Dog) {}let combined = combine(animalFunc, dogFunc); // (x: Dog) => void
上面,所有對 T 的推斷都源於逆變位置,因此我們推斷 T 的最佳公共子型別。這與來自協變位置的推斷形成對比,在協變位置中,我們推斷的是最佳公共超型別。
在模組中快取帶標籤的模板物件
TypeScript 2.6 修復了帶標籤的字串模板生成,以更好地符合 ECMAScript 規範。根據 ECMAScript 規範,每次評估模板標籤時,都應將相同的模板字串物件(相同的 TemplateStringsArray)作為第一個引數傳遞。在 TypeScript 2.6 之前,生成的輸出每次都是一個全新的模板物件。雖然字串內容相同,但這種生成方式影響了使用字串標識進行快取失效的庫,例如 lit-html。
示例
tsexport function id(x: TemplateStringsArray) {return x;}export function templateObjectFactory() {return id`hello world`;}let result = templateObjectFactory() === templateObjectFactory(); // true in TS 2.6
導致生成以下程式碼:
js"use strict";var __makeTemplateObject =(this && this.__makeTemplateObject) ||function(cooked, raw) {if (Object.defineProperty) {Object.defineProperty(cooked, "raw", { value: raw });} else {cooked.raw = raw;}return cooked;};function id(x) {return x;}var _a;function templateObjectFactory() {return id(_a || (_a = __makeTemplateObject(["hello world"], ["hello world"])));}var result = templateObjectFactory() === templateObjectFactory();
注意:此更改引入了一個新的生成輔助函式
__makeTemplateObject;如果您正在將importHelpers與tslib一起使用,請更新到 1.8 或更高版本。
命令列上的本地化診斷資訊
TypeScript 2.6 npm 包附帶了 13 種語言的本地化診斷訊息。使用命令列上的 --locale 標誌時可以使用這些本地化訊息。
示例
俄語錯誤訊息:
shc:\ts>tsc --vVersion 2.6.0-dev.20171003c:\ts>tsc --locale ru --pretty c:\test\a.ts../test/a.ts(1,5): error TS2322: Тип ""string"" не может быть назначен для типа "number".1 var x: number = "string";~
以及日語幫助資訊:
shPS C:\ts> tsc --vVersion 2.6.0-dev.20171003PS C:\ts> tsc --locale ja-jpバージョン 2.6.0-dev.20171003構文: tsc [オプション] [ファイル ...]例: tsc hello.tstsc --outFile file.js file.tstsc @args.txtオプション:-h, --help このメッセージを表示します。--all コンパイラ オプションをすべて表示します。-v, --version コンパイラのバージョンを表示します。--init TypeScript プロジェクトを初期化して、tsconfig.json ファイルを作成します。-p ファイルまたはディレクトリ, --project ファイルまたはディレクトリ 構成ファイルか、'tsconfig.json' を含むフォルダーにパスが指定されたプロジェクトをコンパイルします。--pretty 色とコンテキストを使用してエラーとメッセージにスタイルを適用します (試験的)。-w, --watch 入力ファイルを監視します。-t バージョン, --target バージョン ECMAScript のターゲット バージョンを指定します: 'ES3' (既定)、'ES5'、'ES2015'、'ES2016'、'ES2017'、'ESNEXT'。-m 種類, --module 種類 モジュール コード生成を指定します: 'none'、'commonjs'、'amd'、'system'、'umd'、'es2015'、'ESNext'。--lib コンパイルに含めるライブラリ ファイルを指定します:'es5' 'es6' 'es2015' 'es7' 'es2016' 'es2017' 'esnext' 'dom' 'dom.iterable' 'webworker' 'scripthost' 'es2015.core' 'es2015.collection' 'es2015.generator' 'es2015.iterable' 'es2015.promise' 'es2015.proxy' 'es2015.reflect' 'es2015.symbol' 'es2015.symbol.wellknown' 'es2016.array.include' 'es2017.object' 'es2017.sharedmemory' 'es2017.string' 'es2017.intl' 'esnext.asynciterable'--allowJs javascript ファイルのコンパイルを許可します。--jsx 種類 JSX コード生成を指定します: 'preserve'、'react-native'、'react'。-d, --declaration 対応する '.d.ts' ファイルを生成します。--sourceMap 対応する '.map' ファイルを生成します。--outFile ファイル 出力を連結して 1 つのファイルを生成します。--outDir ディレクトリ ディレクトリへ出力構造をリダイレクトします。--removeComments コメントを出力しないでください。--noEmit 出力しないでください。--strict strict 型チェックのオプションをすべて有効にします。--noImplicitAny 暗黙的な 'any' 型を含む式と宣言に関するエラーを発生させます。--strictNullChecks 厳格な null チェックを有効にします。--noImplicitThis 暗黙的な 'any' 型を持つ 'this' 式でエラーが発生します。--alwaysStrict 厳格モードで解析してソース ファイルごとに "use strict" を生成します。--noUnusedLocals 使用されていないローカルに関するエラーを報告します。--noUnusedParameters 使用されていないパラメーターに関するエラーを報告します。--noImplicitReturns 関數の一部のコード パスが値を返さない場合にエラーを報告します。--noFallthroughCasesInSwitch switch ステートメントに case のフォールスルーがある場合にエラーを報告します。--types コンパイルに含む型宣言ファイル。@<ファイル>
使用 '// @ts-ignore' 註釋抑制 .ts 檔案中的錯誤
TypeScript 2.6 支援透過在違規行上方放置 // @ts-ignore 註釋來抑制 .ts 檔案中的錯誤。
示例
tsif (false) {// @ts-ignore: Unreachable code errorconsole.log("hello");}
// @ts-ignore 註釋會抑制下一行產生的所有錯誤。建議在 @ts-ignore 之後補充說明被抑制的錯誤型別。
請注意,該註釋僅抑制錯誤報告,我們建議極其謹慎地使用此註釋。
更快的 tsc --watch
TypeScript 2.6 帶來了更快的 --watch 實現。新版本優化了使用 ES 模組的程式碼庫的程式碼生成和檢查。檢測到模組檔案中的更改將導致僅重新生成已更改的模組及其依賴檔案,而不是整個專案。擁有大量檔案的專案將從這一更改中獲得最大收益。
新實現還提升了 tsserver 中監視的效能。監視器邏輯已完全重寫,以更快速地響應更改事件。
只寫引用現被標記為未使用
TypeScript 2.6 對 noUnusedLocals 和 noUnusedParameters 編譯器選項進行了修訂。現在,只被寫入但從未被讀取的宣告會被標記為未使用。
示例
在下文中,n 和 m 都將被標記為未使用,因為它們的值從未被讀取。在此之前,TypeScript 只會檢查它們的值是否被引用。
tsfunction f(n: number) {n = 0;}class C {private m: number;constructor() {this.m = 0;}}
此外,僅在其自身函式體內被呼叫的函式也被視為未使用。
示例
tsfunction f() {f(); // Error: 'f' is declared but its value is never read}