TypeScript 筆記:unknown 簡介


Posted by SimonAllen on 2021-08-11

延續上一篇 TS 筆記末尾,若版本允許,使用 unknown 會比 any 更好一點,此篇就來簡介一下 unknown:

unknown

unknown 型別容易與 any 搞混,其在 TypeScript 3.0 版提出,也是所有型別的聯集。unknown 意指未知型別,表示不知道當下是何種型別。使用 unknown 會允許 TypeScript 在之後仍可以賦值為任意型別。

unknown 和 any 的差異:

  • 不能直接操作屬性、方法、建構式
  • 無法重新賦值給 unknown 或 any 外的型別
  • 需要斷言或限縮型別

不能直接操作屬性、方法、建構式

在使用 any 的情境下,我們可以這樣寫,即便數值 1 根本沒有 somethingMethod 這個方法,TypeScript 仍不會報錯可以正常編譯。

let anyValue: any = 1;
anyValue.somethingMethod();

改成 unknown 的情境下,就嚴謹許多,也會出現錯誤。

let unknownValue: unknown = 1;
unknownValue.somethingMethod(); // 出現警告波浪~

無法重新賦值給 unknown 或 any 以外的型別

一但註記 unknown 型別,後續賦值給另外註記 unknown 與 any 變數正常不會報錯:

let unknownValue: unknown;

let foo1: unknown = unknownValue;
let foo2: any = unknownValue;

但是賦值給 unknown 或 any 以外的型別就會報錯:

let unknownValue: unknown;

let foo1: number = unknownValue;
let foo2: string = unknownValue;

需要斷言或限縮型別

一旦變數註記了 unknown,下次使用該變數就要做型別斷言或能讓編譯器做出型別檢查,目的是為了限縮型別,畢竟 unknown 表示未知,不這麼做編譯器會報錯擋著。

例如:

let anyNumber: any = 123;
let unknownNumber: unknown = 123;
anyNumber + 1; 
unknownNumber + 1; // 出現警告波浪~

unknownNumber 出現錯誤提示訊息,所以必須要給其斷言才行。

let anyNumber: any = 123;
let unknownNumber: unknown = 123;
anyNumber + 1; 
(unknownNumber as number) + 1;
// 或者
<number>unknownNumber + 1;

然而,若將上述改成 unknown 與 string 的相加

let anyString: any = "123";
let unknownString: unknown = "123";
anyString + "1";
unknownString + "1";  // 沒有警告波浪~

編譯器這邊推論給過,筆者查閱文件和網路文章沒有看到原因,後來在 FB TypeScript Taiwan 社團發問得到版主的解釋,大意如下:

 number 與 + 運算子搭配,出來的結果是不確定的,尤其是在與 unknown 不確定為合的情境下相加,自然需要斷言。
然而大部分型別用 + 運算子跟 string 型別結合都會變成 string,所以編譯器自然就給過了。

發問傳送門見此

總之,雖然 unknown 和 any 很像,但如同其他網路文章所說的,unknown 像是更安全的 any,開發者若為了自己開發習慣或要改動陳年舊 code,使用 unknown 還比使用 any 好一點。

當下次 JS 社群或靠北工程師又有反對 TS 的鄉民酸「any 啦,我都用 any」,你可以告訴他:「我都用 unknown」

參考

FB社團:TypeScript Taiwan
TypeScript 新手指南
TypeScript: Typed JavaScript at Any Scale.
kobo 電子書:讓TypeScript成爲你前端開發的ACE!
Typescript 初心者手札


#TypeScript









Related Posts

F2E合作社|input group輸入群組|Bootstrap 5網頁框架開發入門

F2E合作社|input group輸入群組|Bootstrap 5網頁框架開發入門

JAVA筆記_網路程式設計

JAVA筆記_網路程式設計

ES6(let 與 const、Template Literals)

ES6(let 與 const、Template Literals)


Comments