今天要來了解 any
和 unknow
,這兩個會放在一起說明是因為性質和用法很相似,但卻有些許不一樣,稍後比較後,就可以明白為什麼了?
在 TypeScript 的眾多型別裡面,any
是一個非常特殊的存在,一般我們型別註記後,Typecript 都會進行型別檢查,唯獨 any
會跳過檢查,會想這是開外掛還是走後門?所以 any
可以相容所有的型別(包括 any
本身)。
當我們宣告一個變數不註記型別,TypeScript 就會推論為 any
。
any
可以賦值任何型別
let cy: any;
cy = []; // 陣列,pass
cy = {}; // 物件,pass
cy = null; // null,pass
cy = undefined; // undefined,pass
cy = true; // 布林,pass
cy = 18; // 數字,pass
cy = "Hello TypeScript"; // 字串,pass
cy = new TypeError(); // Error物件,pass
就因為視為任意型別,所以任意使用各種型別屬性和方法操作,都不會有錯誤,如下:
let cy: any;
cy(); // 函式呼叫,pass
new cy(); // 建立物件,pass
cy[0]; // 取陣列元素,pass
cy.length; // 字串長度,pass
cy.toUpperCase(); // 把字串轉大寫,pass
就以上我們發現,完全毫無使用 TypeScript 意義,這樣編寫出來的程式碼會暴露在不安全的情況下,所以我們能盡量能不用就不用。
可以說是安全版的 any
,究竟是為什麼呢?
unknown
和 any
共通點:可以接受任何型別賦值。
let cy: unknown;
cy = []; // 陣列,pass
cy = {}; // 物件,pass
cy = null; // null,pass
cy = undefined; // undefined,pass
cy = true; // 布林,pass
cy = 18; // 數字,pass
cy = "Hello TypeScript"; // 字串,pass
cy = new TypeError(); // Error物件,pass
那屬性和方法的操作呢?
let cy: unknown;
cy(); // 函式呼叫,噴錯
new cy(); // 建立物件,噴錯
cy[0]; // 取陣列元素,噴錯
cy.length; // 字串長度,噴錯
cy.toUpperCase(); // 把字串轉大寫,噴錯
雖說似乎比 any
安全一點,不過好像什麼事也都不能做。
let isUnknown: unknown;
let cy: string = isUnknown; //Error: Type 'unknown' is not assignable to type 'number'
如果我們要在 unknown
型別下進行屬性或方法操作,透過 Type Guards
進行限縮確切跟 TypeScript 說明目前是何種型別才可以,如下:
let isUnknown: unknown;
if (typeof isUnknown === 'string') {
let cy: string = isUnknown;
cy.length
}
Type Guards: 為型別檢測,我們在進行型別判斷時常會用到的 typeof
、 instanceof
都是。
簡單複習 any
和 unknown
差異
相同:可以接受任意型別。
不同:any
可以進行任意屬性或方法操作,unknown
則是要透過型別檢測限縮之後才可以。
今天簡單瞭解 any
& unknown
,明天讓我們繼續努力進步。