做者:Dr. Axel Rauschmayer翻譯:瘋狂的技術宅html
原文:https://2ality.com/2020/06/an...前端
未經容許嚴禁轉載程序員
在 TypeScript中,any
和 unknown
是包含全部值的類型。在本文中,咱們將會研究它們是怎樣工做的。面試
any
and unknown
are so-called top types in TypeScript. Quoting Wikipedia:typescript
any
和 unknown
在 TypeScript 中是所謂的「頂部類型」。如下文字引用自 Wikipedia:segmentfault
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 // ··· }
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); } }