TypeScript递归类型声明对象允许额外属性赋值问题咨询
问题原因解释
核心原因是 TypeScript 的**多余属性校验(Excess Property Checking)**存在适用场景限制,属于 TypeScript 的设计特性而非 bug。
1. 多余属性校验的触发规则
TypeScript 默认采用结构类型系统:只要对象包含目标类型要求的所有必要属性,即使存在额外属性,也会被判定为类型兼容。
而多余属性校验只是一个针对性的保护性检查,仅会在你把对象字面量直接赋值给显式指定类型的变量时触发,不属于通用的类型兼容规则。
举个简单示例:
type User = { name: string }; // 直接赋值对象字面量,触发多余属性检查,预期报错 const u: User = { name: "张三", age: 18 }; // 先定义临时对象再赋值,不会触发多余属性检查,不会报错 const temp = { name: "张三", age: 18 }; const u2: User = temp;
2. 声明对象时嵌套额外属性不报错的原因
你定义的 ObjWrappedProps 是通过递归条件类型计算得到的多层交叉类型(由 & 连接的组合类型),嵌套在内部的对象字面量并不是直接赋值给某个显式指定类型的变量,TypeScript 不会对这些深层嵌套的对象字面量触发严格的多余属性校验,只要它们包含了类型要求的所有必要属性(如prop3、__childProps__等),即使存在额外属性也会被允许。
3. 后续赋值报错的原因
对象创建完成后,你直接给obj.extraProp、obj.__childProps__.__childProps__.extraProp赋值时,TypeScript 会直接读取对应位置的类型定义,检查待赋值的属性是否存在于该类型的定义中,不存在就会抛出错误。这是普通的属性存在性校验,和多余属性校验无关。
补充:如何避免声明时意外添加多余属性
如果需要在声明阶段就校验嵌套对象的多余属性,可以手动给每一层嵌套的对象字面量指定明确类型:
const obj: ObjWrappedProps = { prop1: 'allowed', __childProps__: { prop2: 'allowed', __childProps__: { prop3: 'allowed', extraProp: 'now it will error', // 手动指定类型后此处会报错 __childProps__: { mainProp: 'allowed', } as { mainProp: string }, } as { prop3: string, __childProps__: { mainProp: string } }, }, };
内容的提问来源于stack exchange,提问作者nerdlinger
相关产品推荐
相关产品推荐

