TypeScript异步实例化抽象类:protected构造函数类型赋值报错
解决TypeScript中protected构造函数与静态工厂方法的类型不兼容问题
错误原因分析
你遇到的错误源于定义的Constructor<T>类型要求构造函数为public,但BaseController及其子类的构造函数被设置为protected,导致typeof InheritedController(包含protected构造函数)无法赋值给要求public构造的Constructor<T>类型,触发类型不匹配报错。
解决方案
以下是两种可行的修复方式,核心是让静态方法的this约束类型兼容protected构造函数:
方案1:调整构造函数类型定义
将Constructor<T>改为支持protected构造的抽象构造函数类型:
// 用abstract修饰构造函数类型,适配protected构造场景 type Constructor<T> = abstract new () => T; export default abstract class BaseController { static async create<T extends BaseController>( this: Constructor<T> ): Promise<T> { const controller = new this(); await controller.initialize(); return controller; } protected constructor() {} protected async initialize() { console.log('Initialising asynchronously...'); } } class InheritedController extends BaseController { protected async initialize(): Promise<void> { // await loading data } } const controller = await InheritedController.create();
方案2:直接约束静态方法的this类型
如果不想修改全局的Constructor<T>类型,可直接在create方法中指定精确的this约束:
export default abstract class BaseController { static async create<T extends BaseController>( this: { new (): T } & typeof BaseController ): Promise<T> { const controller = new this(); await controller.initialize(); return controller; } protected constructor() {} protected async initialize() { console.log('Initialising asynchronously...'); } } class InheritedController extends BaseController { protected async initialize(): Promise<void> { // await loading data } } const controller = await InheritedController.create();
原理说明
- TypeScript中,带有
protected构造函数的类,其构造函数类型无法赋值给要求public构造的new () => T类型。 abstract new () => T表示构造函数为protected的类类型,恰好匹配抽象基类及子类的构造函数权限。- 在基类静态方法中调用
new this()是合法的,因为基类有权访问子类的protected成员。
内容的提问来源于stack exchange,提问作者Pinocchio
相关产品推荐
相关产品推荐

