将子类分配给父类类型的属性

Assigning child class to a parent class typed property

本文关键字:类型 属性 父类 子类 分配      更新时间:2023-09-26

我有以下两个基类:

class BaseModel {}
class BaseService{
  protected model:BaseModel;
}

现在,我想为一个特定的用例实现BaseHelper和BaseService,并为我的属性分配一个派生类。

class MyModel extends BaseModel{
  constructor(param:string){
    super();
  }
}
class MyService extends BaseService {
  model = MyModel;  
}

但是,这给了我错误类型"typeof MyModel"不可分配给类型"BaseModel"。

重要提示:我想附加类MyModel,而不是类MyModel的实例

您需要使用new关键字(new MyModel())实例化MyModel
您分配了实际的类(model = MyModel),而不是它的实例

此外,您可能希望使BaseService通用:

class BaseModel {}
class BaseService<T extends BaseModel> {
    protected model: T;
    constructor(model: T) {
        this.model = model;
    }
}
class MyModel extends BaseModel{}
class MyService extends BaseService<MyModel> {
    constructor() {
        super(new MyModel());
    }
}

(操场代码)


编辑

如果你需要类而不是实例,那么类似于:

class BaseModel {}
type BaseModelConstructor = { new(): BaseModel };
class BaseService {
    protected modelCtor: BaseModelConstructor;
}
class MyModel extends BaseModel {}
class MyService extends BaseService {
    modelCtor = MyModel;  
}

(操场代码)

或者你也可以在这里使用泛型:

class BaseModel {}
type BaseModelConstructor<T extends BaseModel> = { new(): T };
class BaseService<T extends BaseModel> {
    protected modelCtor: T;
}
class MyModel extends BaseModel {}
class MyService extends BaseService<BaseModel> {
    modelCtor = MyModel;  
}

(操场代码)


如果派生类有不同的ctor签名,那么您可以在基本的ctor类型中处理它:

type BaseModelConstructor<T extends BaseModel> = { new(...args: any[]): T };

在这里,您可以传递任何计数和类型的参数,但也可以提供不同的签名:

type BaseModelConstructor<T extends BaseModel> = { 
    new(): T;
    new(str: string): T;
    new(num: number, bool: boolean): T;
};

但您也可以为每个派生类使用不同的类型:

type MyModelConstructor = { new(param: string): MyModel };

model应该是MyModel:的实例

class MyModel extends BaseModel{}
class MyService extends BaseService {
  model = new MyModel()
}

使用BaseModel 实例

class MyService extends BaseService {
  model = new MyModel();  
}
相关文章: