TypeScript用new创建对象时不做类型检查?为何someCat2调用test未报类型错误
差异根因拆解
两个变量的实际类型判定逻辑
- 对于
someCat:它是直接赋值的对象字面量,TypeScript会为其推断封闭、精确的结构类型,即{ cat: string }。这个类型明确只包含cat属性,不存在接口A要求的必需属性x: number,因此传入test时会因结构不匹配触发类型报错,这是完全符合结构类型预期的行为。 - 对于
someCat2:它是调用无类型标注的构造函数MakeCat生成的实例。由于MakeCat没有为内部的this显式指定类型、也没有标注返回值类型,在未开启noImplicitThis检查的默认编译配置下,TypeScript会将构造函数内部的this隐式推断为any类型,对应new生成的实例也会被判定为any。而any类型本身可以匹配任意结构的类型,因此传入test时不会触发任何类型检查报错。如果开启严格模式的noImplicitThis规则,这段构造函数代码本身就会先报出“this存在隐式any类型”的错误,不会出现传参不报错的情况。
对应设计逻辑
这种校验强度的差异是TypeScript兼容原生JavaScript动态特性的权衡设计:
- 对缺少显式类型约束的构造函数场景,TS默认采用宽松判定:传统JS中构造函数生成的实例往往会在创建后被外部动态挂载任意属性,如果TS强行将构造函数内部挂载的属性认定为实例的全部结构,会在大量遗留JS迁移场景中产生无意义的误报。
- 对直接赋值的对象字面量采用严格封闭校验(即对象新鲜度规则),是为了精准识别开发笔误:比如本意传
{x: 1}却误写为{cat: "miao"},如果TS不锁死字面量的属性结构,这类明显的书写错误会被直接放过,增加调试成本。
修正校验行为的方式
如果需要让构造函数生成的实例和对象字面量保持一致的严格校验强度,只需为构造函数的this添加明确的类型标注即可:
interface A { x: number; } function test(something: A) {} // 显式标注this的结构,锁死实例的属性范围 function MakeCat(this: { cat: string }) { this.cat = "miao"; } let someCat2 = new MakeCat(); test(someCat2); // 此时会和someCat一样,提示缺少必需的x属性
内容的提问来源于stack exchange,提问作者Miao
相关产品推荐
相关产品推荐

