为何(() => 22)在extends {[k:string]:any}与unknown时结果不同?
为什么P1和P2的取值不同?
先看代码里的两个类型判断:
type P1 = (() => 22) extends {[k:string]:any} ? 1:2 // P1 == 1 type P2 = (() => 22) extends {[k:string]:unknown} ? 1:2 // P2 == 2
核心原因在于**any和unknown在类型兼容性上的本质差异**:
对于
P1的{[k:string]:any}:any是TypeScript里的“万能类型”,它完全绕过类型检查规则——任何类型都能兼容any。函数类型本质是对象类型,自带call、apply等内置属性,这些属性的类型不管是什么,都能被any兼容,所以(() => 22)可以匹配这个索引签名,结果返回1。对于
P2的{[k:string]:unknown}:unknown是类型安全的顶级类型,它要求所有符合索引签名的属性类型都必须是unknown或者能兼容它,但反过来,具体类型不能自动兼容unknown的索引签名。函数的内置属性(比如call)是具体的函数类型,不是unknown,TypeScript不会为了满足索引签名把这些具体类型“降级”成unknown,所以这个extends判断不成立,结果返回2。
内容的提问来源于stack exchange,提问作者gmoniava
相关产品推荐
相关产品推荐

