1. TypeScript 中 any 和 unknown 都可以指任意类型,那么这两者之间有什么不同呢?
-
TypeScript 可以推导出
any
类型,但无法推导出unknown
类型,如果要使用unknow
类型,必须显式注解 -
使用
unknown
类型,除了相等比较外,都需要先说明变量的类型:let num: unknown = 1 if (num > 2) { // 此时编辑器会对 num 报错,提示:Object is of type 'unknown'. // } if (typeof num === 'number' && num > 2) { // OK, 已经通过typeof判断num是否是number类型了,所以可以比较 }
如果是
any
类型的话,那就是随便用了,但这样做就丢失了类型安全,所以一般如果不知道当前变量的类型,建议先使用unknown
,除非特殊情况,否则不建议使用any
,如果要使用any
,则最好是显式注解
2. TypeScript 对象类型中的 object
, {}
, Object
有什么区别?
它们之间的相同之处就是都可以用来表示对象的类型,它们之间的区别比较细微:
-
object
object
可以指代除了基本类型或者说原始类型(number, string, null, undefined, symbol
)之外的类型,如果是不关心属性的对象,可以使用object
类型 -
对象字面量类型
{}
这个类型有点微妙,如果是非空的字面量对象,TypeScript 会要求你严格按照定义的属性名和类型来给变量赋值,但如果是个空的字面量对象用作类型的时候,在初始化的时候,可以指代除了
null
和undefined
之外的所有类型,而编辑器不会报错,不过如果是要对这个数据进行后续的操作时,编辑器有时还是会报错的:// 这些声明都是可以的,在声明的时候编辑器不会报错 let n: {} = 1 let s: {} = 'string' let arr: {} = [1, 2, '3'] let func: {} = () => console.log('something') let symb: {} = Symbol('symb') let o: {} = {} // 下面这两个声明,编辑器会报错 let nl: {} = null // Type 'null' is not assignable to type '{}'. let u: {} = undefined // Type 'undefined' is not assignable to type '{}'. // 以下的一些操作会报错 n.toFixed(2) // Property 'toFixed' does not exist on type '{}'. s.slice(0, 2) // Property 'slice' does not exist on type '{}'. arr.push(1) // Property 'push' does not exist on type '{}'. func() // This expression is not callable. Type '{}' has no call signatures.
通过测试和观察,可以大致得出,用空对象字面量声明类型时,会根据原型链定位到
Object
上,而除了null
和undefined
外,其他的类型通过prototype
或者__proto__
最后都会找到Object
上,所以为什么用空对象字面量可以注解null
和undefined
之外的所有类型了。也因此,对这些变量调用不在Object.prototype
上的方法时会报错的原因了 -
Object
表现基本与空对象字面量类型{}
一致,大概的区别就是,{}
是通过原型链定位到Object
,而Object
是显式指明