为什么TypeScript接口赋值其他对象时未强制校验多余属性?
问题解答
这个差异是TypeScript两套不同的检查规则导致的:
- 触发报错的直接赋值场景,走的是对象字面量专属的额外属性检查
当你直接把对象字面量赋值给指定类型的变量时,TS会做严格的额外属性校验:只要字面量中出现了目标类型未定义的属性,就会直接抛出错误。这个规则是为了减少开发者手写属性名拼写错误、多余传参这类低级问题,是专门针对字面量直接赋值场景的特殊限制。 - 不报错的二次赋值场景,走的是通用结构类型兼容性检查
TypeScript的类型系统默认是结构类型(也就是常说的鸭子类型),判断两个类型是否兼容的核心规则是:只要源类型至少包含目标类型的所有必填属性,就判定为兼容,源类型多余的属性不会触发报错。你先声明的samePerson变量会被TS自动推导为{ name: string, id: number }类型,这个类型完全覆盖了Person接口的要求,所以可以正常赋值给Person类型的person变量。
至于最终person对象携带id属性的问题,是因为TS的所有类型检查都只在编译阶段执行,编译后所有类型信息都会被抹除,不会修改运行时的实际对象结构,赋值操作只是把原对象的引用传过去,所以原对象的所有属性都会保留。
如果你想让第二种场景也触发多余属性报错,可以给samePerson显式加上Person类型注解:
// 此时会触发额外属性检查,直接报错 const samePerson: Person = { name: 'Jack', id: 209 };
内容的提问来源于stack exchange,提问作者Fadi
相关产品推荐
相关产品推荐

