为何TypeScript中FooInterface报TS2345错误,FooType却不报错?
为什么interface定义的类型报错,而type定义的不报错?
核心原因是TypeScript对接口(interface)和类型别名(type alias)的兼容性检查逻辑存在差异,具体体现在索引签名的处理上:
1. 类型别名FooType的兼容性逻辑
FooType是用type定义的结构类型,当把它赋值给FooType & Partial<Record<string, string>>时,TypeScript会做结构宽松匹配:
Partial<Record<string, string>>的要求是「所有属性的类型都是string | undefined」,而FooType的唯一属性foo是string类型,完全符合这个要求;- TypeScript不需要
FooType显式声明索引签名,只要结构上没有冲突,就允许赋值。
2. 接口FooInterface的兼容性逻辑
FooInterface是用interface定义的,TypeScript对接口的兼容性检查更严格:
FooInterface & Partial<Record<string, string>>要求传入的类型同时满足FooInterface和Partial<Record<string, string>>;Partial<Record<string, string>>包含[key: string]: string | undefined的索引签名,而FooInterface没有显式声明这个索引签名,TypeScript会默认认为FooInterface可能存在非string类型的属性(即使实际没有),因此判定它不兼容Partial<Record<string, string>>,抛出TS2345错误。
解决方法
如果要让FooInterface也能正常赋值,只需要给它加上兼容的索引签名即可:
interface FooInterface { foo: string; [key: string]: string | undefined; // 显式声明索引签名 }
内容的提问来源于stack exchange,提问作者TN.
相关产品推荐
相关产品推荐

