一,unknown
和 any
的主要区别
unknown
和 any
的主要区别是 unknown
类型会更加严格:在对 unknown
类型的值执行大多数操作之前,我们必须进行某种形式的检查。而在对 any
类型的值执行操作之前,我们不必进行任何检查。
二,any
类型
自从 TypeScript 在 2012 年发布第一个版本以来 any
类型就一直存在。它代表所有可能的 JavaScript 值 — 基本类型,对象,数组,函数,Error,Symbol,以及任何你可能定义的值。
在 TypeScript 中,任何类型都可以被归为 any 类型。这让 any
类型成为了类型系统的 顶级类型 (也被称作 全局超级类型)。
这是一些我们赋值给 any
类型的代码示例:
let value: any;
value = true; // OK
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
value = Math.random; // OK
value = null; // OK
value = undefined; // OK
value = new TypeError(); // OK
value = Symbol("type"); // OK
TypeScript允许我们对 类型的值执行任何操作,而无需事先执行任何形式的检查。
在上述例子中,变量 value
被定义成类型 any
。也是因此,TypeScript 认为以下所有操作都是类型正确的:
let value: any;
value.foo.bar; // OK
value.trim(); // OK
value(); // OK
new value(); // OK
value[0][1]; // OK
这许多场景下,这样的机制都太宽松了。使用any
类型,可以很容易地编写类型正确但是执行异常的代码。如果我们使用 any
类型,就无法享受 TypeScript 大量的保护机制。
但如果能有顶级类型也能默认保持安全呢?这就是 unknown
到来的原因。
三,unknown
类型
就像所有类型都可以被归为 any
,所有类型也都可以被归为 unknown
。这使得 unknown
成为 TypeScript 类型系统的另一种顶级类型(另一种是 any
)。
这是我们之前看到的相同的一组赋值示例,这次使用类型为 unknown
的变量:
let value: unknown;
value = true; // OK
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
value = Math.random; // OK
value = null; // OK
value = undefined; // OK
value = new TypeError(); // OK
value = Symbol("type"); // OK
对 value
变量的所有赋值都被认为是类型正确的。
当我们尝试将类型为 unknown
的值赋值给其他类型的变量时会发生什么?
let value: unknown;
let value1: unknown = value; // OK
let value2: any = value; // OK
let value3: boolean = value; // Error
let value4: number = value; // Error
let value5: string = value; // Error
let value6: object = value; // Error
let value7: any[] = value; // Error
let value8: Function = value; // Error