TypeScript条件类型中type与interface的差异疑问
为什么同结构的type和interface在TypeScript条件类型extends判断中结果不同?
先看这个TypeScript代码示例(tsc v5.1.6):
type Handlers = { [name: string | number]: () => void } type H1 = { "click": () => void } interface H2 { "click": () => void } type A = H1 extends Handlers ? 'yes' : 'no' // yes type B = H2 extends Handlers ? 'yes' : 'no' // no
尽管H1和H2的结构完全一致,但类型A的结果为'yes',类型B的结果为'no'。这是因为TypeScript中type别名与interface的兼容性规则存在差异,核心在于索引签名的匹配逻辑:
- 对于
type别名(如H1):条件类型的extends判断采用结构兼容性检查,只要H1的所有属性都符合目标类型(Handlers)的索引签名约束,就判定为兼容。这里H1的click属性类型是() => void,完全符合Handlers中索引值的类型要求,所以返回'yes'。 - 对于
interface(如H2):它的兼容性检查规则更严格,若目标类型带有索引签名,interface必须显式声明对应的索引签名才能被判定为兼容。H2只定义了click属性,没有显式添加[name: string | number]: () => void这样的索引签名,因此不满足Handlers的约束,返回'no'。
这种差异属于TypeScript类型系统的底层设计细节,本质是interface作为“命名类型”,在兼容性校验时对索引签名的要求比匿名的type别名更严格——interface需要显式匹配索引签名,而type别名仅需结构上的属性符合索引签名要求即可。
内容的提问来源于stack exchange,提问作者top2307
相关产品推荐
相关产品推荐

