TypeScript重载抽象类泛型方法返回类引用报错求助
TypeScript泛型抽象方法重载返回类引用的类型错误解决
错误信息
Type 'typeof ServiceChecklistResponse' is not assignable to type 'Constructor<ServiceChecklistResponse>'. Type 'ServiceChecklistResponse' is not assignable to type 'ServiceChecklistResponse'. Two different types with this name exist, but they are unrelated. 'ServiceChecklistResponse' could be instantiated with an arbitrary type which could be unrelated to 'ServiceChecklistResponse'. Type 'typeof AnotherModel' is not assignable to type 'Constructor<AnotherModel>'. Type 'AnotherModel' is not assignable to type 'AnotherModel'. Two different types with this name exist, but they are unrelated. 'AnotherModel' could be instantiated with an arbitrary type which could be unrelated to 'AnotherModel'.
问题代码
type Constructor<T> = new (...args: any[]) => T; class ServiceChecklistResponse { } class AnotherModel { } abstract class AbstractView { getJsonDataModelRef<T>(): Constructor<T> | null { return null; } getAnotherDataModel<T>(): Constructor<T> | null { return null; } } class testView extends AbstractView { getJsonDataModelRef<ServiceChecklistResponse>(): Constructor<ServiceChecklistResponse> | null { return ServiceChecklistResponse; } getAnotherDataModel<AnotherModel>(): Constructor<AnotherModel> | null { return AnotherModel; } }
错误原因
子类重写方法时,<ServiceChecklistResponse>和<AnotherModel>被声明为新的泛型类型参数,而非指定父类方法泛型的具体类型。此时TypeScript会将这些名称视为局部泛型参数,和全局定义的同名类完全无关,导致返回的类引用类型无法匹配泛型约束的类型。
修复方案
方案1:直接指定父类方法的泛型具体类型
子类重写方法时,无需重新声明泛型参数,直接明确返回类型对应的目标类即可:
type Constructor<T> = new (...args: any[]) => T; class ServiceChecklistResponse { } class AnotherModel { } abstract class AbstractView { getJsonDataModelRef<T>(): Constructor<T> | null { return null; } getAnotherDataModel<T>(): Constructor<T> | null { return null; } } class testView extends AbstractView { getJsonDataModelRef(): Constructor<ServiceChecklistResponse> | null { return ServiceChecklistResponse; } getAnotherDataModel(): Constructor<AnotherModel> | null { return AnotherModel; } }
方案2:将泛型提升到类级别(更优雅的设计)
如果每个子类对应固定的模型类,建议将泛型从方法级别移到抽象类级别,子类继承时直接绑定具体类型:
type Constructor<T> = new (...args: any[]) => T; class ServiceChecklistResponse { } class AnotherModel { } // 抽象类声明类级泛型 abstract class AbstractView<TJsonModel, TAnotherModel> { getJsonDataModelRef(): Constructor<TJsonModel> | null { return null; } getAnotherDataModel(): Constructor<TAnotherModel> | null { return null; } } // 子类继承时指定具体模型类型 class testView extends AbstractView<ServiceChecklistResponse, AnotherModel> { getJsonDataModelRef(): Constructor<ServiceChecklistResponse> | null { return ServiceChecklistResponse; } getAnotherDataModel(): Constructor<AnotherModel> | null { return AnotherModel; } }
验证实例化代码
修复后,控制器的实例化代码可正常运行且类型安全:
const myView = new testView(); const Model = myView.getJsonDataModelRef(); if (Model) { const foo = new Model(); // foo类型自动推导为ServiceChecklistResponse }
内容的提问来源于stack exchange,提问作者slushpuppy
相关产品推荐
相关产品推荐

