在 TypeScript中,any 和 unknown 是包含所有值的類型。在本文中,我們將會研究它們是怎樣工作的。
TypeScript 的兩種頂級類型
any 和 unknown 在 TypeScript 中是所謂的“頂部類型”。以下文字引用自 Wikipedia:
top type [...]是 通用(universal) 類型,有時也稱為 通用超類型,因為在任何給定類型系統中,所有其他類型都是子類型[...]。通常,類型是包含了其相關類型系統中所有可能的[值]的類型。
也就是說,當把類型看作是值的集合時,any 和 unknown 是包含所有值的集合。順便說一句,TypeScript 還有 bottom type never,它是空集。
頂級類型 any
如果一個值的類型為 any,那么我們就可以用它任何事:
function func(value: any) { // 僅允許數字,但它們是 `any` 的子類型 5 * value; // 通常,`value` 的類型簽名必須包含 .propName value.propName; // 通常只允許帶有索引簽名的數組和類型 value[123]; }
任何類型的值都可以賦值給 any 類型:
let storageLocation: any; storageLocation = null; storageLocation = true; storageLocation = {};
類型 any 也可被可賦值給每一種類型:
function func(value: any) { const a: null = value; const b: boolean = value; const c: object = value; }
使用 any,我們將會失去通常由 TypeScript 的靜態類型系統所給予的所有保護。因此,如果我們無法使用更具體的類型或 unknown,則只能將其用作最后的手段。
示例:jsON.parse()
jsON.parse() 的結果取決於動態輸入,這就是其返回類型為 any 的原因(我從函數簽名中省略了參數 reviver):
JSON.parse(text: string): any;
在 unknown 類型出現之前,JSON.parse() 就已經被添加到了 TypeScript中。否則它的返回類型可能會是 unknown。
示例:String()
把任意值轉換為字符串的函數 String() 具有以下類型簽名:
interface StringConstructor { (value?: any): string; // call signature // ··· }
vi設計http://www.maiqicn.com 辦公資源網站大全https://www.wode007.com
頂級類型 unknown
unknown 類型是 any 的類型安全版本。每當你想使用 any 時,應該先試着用 unknown。
在 any 允許我們做任何事的地方,unknown 的限制則大得多。
在對 unknown 類型的值執行任何操作之前,必須先通過以下方法限定其類型:
類型斷言
function func(value: unknown) { // @ts-ignore: Object is of type 'unknown'. value.toFixed(2); // Type assertion: (value as number).toFixed(2); // OK }
相等:
function func(value: unknown) { // @ts-ignore: Object is of type 'unknown'. value * 5; if (value === 123) { // equality // %inferred-type: 123 value; value * 5; // OK } }
類型防護:
function func(value: unknown) { // @ts-ignore: Object is of type 'unknown'. value.length; if (typeof value === 'string') { // type guard // %inferred-type: string value; value.length; // OK } }
斷言函數:
function func(value: unknown) { // @ts-ignore: Object is of type 'unknown'. value.test('abc'); assertionFunction(value); // %inferred-type: RegExp value; value.test('abc'); // OK } function assertionFunction(arg: unknown): asserts arg is RegExp { if (! (arg instanceof RegExp)) { throw new TypeError('Not a RegExp: ' + arg); } }