如何在TypeScript中检测构造函数类型不匹配问题?
检测TypeScript中构造函数类型不匹配的问题
以下TypeScript代码可正常编译,但Obj和Sub的构造函数签名与声明的ObjConstructor类型不匹配,调用foo(Sub)传入不符合要求的构造函数时未触发类型错误,如何检测这类构造函数类型不匹配问题?
type ObjConstructor = new (name: string) => Obj // 声明的构造函数类型:接收string参数 // 用接口定义效果一致 // interface ObjConstructor { // new (name: string): Obj // } class Obj { constructor(private id: number) { } // 冲突构造函数:接收number参数 print() { console.log(this.id) } } class Sub extends Obj { constructor() { super(0) } // 冲突构造函数:无参数 } function foo(f: ObjConstructor) { // 函数期望签名:接收string参数的构造函数 const obj = new f('name') if (obj instanceof Sub) { obj.print() } } foo(Sub) // 传入了不符合签名的构造函数,却未触发错误
解决方法
启用严格函数类型检查
在tsconfig.json中开启"strictFunctionTypes": true,TypeScript会以更严格的逆变规则检查函数(包括构造函数)的参数类型兼容性。启用后,Sub的无参数构造函数无法赋值给要求接收string参数的ObjConstructor类型,会直接触发类型错误,从编译阶段阻止此类问题。显式约束类的构造函数签名
让类直接实现构造函数接口,强制构造函数匹配声明的类型:interface ObjConstructor { new (name: string): Obj; } class Obj implements ObjConstructor { private id: number; constructor(name: string) { this.id = Number(name); // 根据业务逻辑处理string参数 } print() { console.log(this.id) } } class Sub extends Obj { constructor(name: string) { super(name); // 子类必须遵循父类的构造函数签名 } }这样类的构造函数必须匹配接口定义,子类也需继承对应签名,不匹配时会直接报错。
运行时补充检查
如果需要在运行时也能检测构造函数是否符合要求,可以在foo函数中添加参数个数或逻辑检查:function foo(f: ObjConstructor) { if (f.length !== 1) { throw new Error("构造函数必须接收一个参数"); } const obj = new f('name'); // ... 其他逻辑 }
内容的提问来源于stack exchange,提问作者Sonia Kidman
相关产品推荐
相关产品推荐

