TypeScript构造签名不匹配报错,如何解决?是否必须用class?
问题解决:构造签名不匹配的报错处理
首先明确:不需要必须用class实现,下面提供两种无需class的解决方案,以及class实现作为参考。
问题原因
你定义的foo是普通函数,TypeScript默认只为它推断出调用签名(即(name: string) => void),但fn要求的参数是带有构造签名(new (name: string): NewObject)的构造函数类型,所以类型不匹配导致报错。
解决方案1:类型断言
直接给foo添加类型断言,告诉TypeScript它符合NewConstructor类型:
type NewObject = { name: string; } type NewConstructor = { new (name: string): NewObject; }; function fn(ctor: NewConstructor) { return new ctor('John'); } function foo(name: string) { this.name = name; }; fn(foo as NewConstructor); // 类型断言解决报错
注意:这种方式需要确保运行时foo确实会被用new调用(这里fn内部就是这么做的),否则直接调用foo会导致this指向全局对象(非严格模式)或undefined(严格模式),引发错误。
解决方案2:显式指定函数类型
定义foo时就明确它的类型为NewConstructor,同时添加this参数的类型注解,让TypeScript知道作为构造函数时this的指向:
type NewObject = { name: string; } type NewConstructor = { new (name: string): NewObject; }; function fn(ctor: NewConstructor) { return new ctor('John'); } // 显式指定类型,并添加this参数注解 const foo: NewConstructor = function(this: NewObject, name: string) { this.name = name; }; fn(foo); // 无报错
这种方式更安全,TypeScript会在编译期就检查函数内部对this的使用是否符合NewObject类型。
可选方案:用class实现
如果习惯用class语法,也可以这么写,本质上class的构造函数就是符合构造签名类型的:
type NewObject = { name: string; } type NewConstructor = { new (name: string): NewObject; }; function fn(ctor: NewConstructor) { return new ctor('John'); } class Foo implements NewObject { name: string; constructor(name: string) { this.name = name; } } fn(Foo); // 无报错
内容的提问来源于stack exchange,提问作者Lamantin
相关产品推荐
相关产品推荐

