TypeScript 3.3來了!快看看有什麼新功能
翻譯:瘋狂的技術宅
本文首發微信公眾號:jingchengyideng
歡迎關注,每天都給你推送新鮮的前端技術文章
關注後回覆“體系”,檢查自己的前端知識體系是否完整
改進了呼叫聯合型別的行為
在TypeScript的早期版本中,不同的聯合型別如果想互相訪問其取值,它們引數的取值列表必須完全一致才行。
type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number;// 吃水果並對它們排名 type ColorConsumer = (color: Color) => string;// 處理顏色並對其進行描述 declare let f: FruitEater | ColorConsumer; // Cannot invoke an expression whose type lacks a call signature. // 無法呼叫這個表示式,因為缺少呼叫簽名型別。 // Type 'FruitEater | ColorConsumer' has no compatible call signatures.ts(2349) // 型別 'FruitEater | ColorConsumer' 沒有相容的呼叫簽名.ts(2349) f("orange");
不管怎樣,在上面的例子中,FruitEater
和ColorConsumer
都應該能夠接受字串"orange"
,並返回number
或string
型別才對。
在TypeScript 3.3中,下面這段程式碼將不再會報錯。
type Fruit = "apple" | "orange"; type Color = "red" | "orange"; type FruitEater = (fruit: Fruit) => number;// 吃水果並對它們排名 type ColorConsumer = (color: Color) => string;// 處理顏色並對其進行描述 declare let f: FruitEater | ColorConsumer; f("orange"); // 可以正常工作!將返回一個'number | string'. f("apple");// error - Argument of type '"red"' is not assignable to parameter of type '"orange"'. f("red");// error - Argument of type '"red"' is not assignable to parameter of type '"orange"'.
在TypeScript 3.3中,這些引數會互相交織在一起然後建立新簽名。
在上面的例子中,fruit
和color
的引數列表會被交叉到一起產生新的Fruit&Color
型別的引數。Fruit & Color
會處理為("apple" | "orange") & ("red" | "orange")
,它等同於("apple" & "red") | ("apple" & "orange") | ("orange" & "red") | ("orange" & "orange")
。 那些不可能的組合被處理成never
,到最後留下了"orange" & "orange"
這個組合,結果只能是"orange"
。
注意
當聯合中最多隻有一個型別具有多個過載時,這種新行為才會出現,並且聯合中最多隻能有一個型別具有通用簽名。 這意味著number[] | string[]
這種形式 ,在map
(通用)這樣的方法中仍然不可以呼叫。
另一方面,在forEach
這樣的方法中現在可以呼叫,但是在noImplicitAny
下可能存在一些問題。
interface Dog { kind: "dog" dogProp: any; } interface Cat { kind: "cat" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach(animal => { //~~~~~~ error! // 引數'animal'隱式含有'any'型別。 });
在TypeScript 3.3中,這仍然很嚴格,新增顯式型別註釋將解決這個問題。
interface Dog { kind: "dog" dogProp: any; } interface Cat { kind: "cat" catProp: any; } const catOrDogArray: Dog[] | Cat[] = []; catOrDogArray.forEach((animal: Dog | Cat) => { if (animal.kind === "dog") { animal.dogProp; // ... } else if (animal.kind === "cat") { animal.catProp; // ... } });
使用--build --watch
檢查複合專案的增量檔案
TypeScript 3.0 引入了一個用於構建過程的被稱為“複合專案”的新功能。 其目的之一是確保使用者可以將大型專案拆分為更小的部分,從而能夠快速構建,同時保留專案結構,而不會影響現有的 TypeScript 體驗。 正式因為有了複合專案,TypeScript 可以用--build
模式僅重新編譯部分專案和依賴項集。 您可以把它視為對專案間構建的優化。
TypeScript 2.7還引入了--watch
模式,通過新的增量“構建器”API進行構建。 該模式只重新檢查和傳送被修改的,可能會影響型別檢查的原始碼檔案和依賴。 您可以將其視為對專案內構建的優化。
在3.3版本之前,在使用--build --watch
構建複合專案時,實際上並沒有使用這種監視增量檔案的基礎結構。 在--build --watch
模式下,如果一個專案中有了更新,將會強制完全重新構建該專案,而不是檢查專案中有哪些檔案受到影響。
在TypeScript 3.3中,--build
模式的--watch
標誌也可以利用增量檔案機制進行監視了。 這可能意味著在--build --watch
模式下構建速度能將會更快。 在我們的測試中,此功能使--build --watch
的構建時間比原來縮短了50%到75%。 您可以閱讀與檔案修改時的原始拉取請求相關的更多內容
來檢視這些資料,我們相信大多數使用複合專案的使用者將會在此處得到更好的體驗。
本文首發微信公眾號:jingchengyideng
歡迎關注,每天都給你推送新鮮的前端技術文章
關注後回覆“體系”,檢查自己的前端知識體系是否完整