Assigning child class to a parent class typed property

↘锁芯ラ 提交于 2020-01-05 05:45:14

问题


I do have the following 2 base clases:

class BaseModel {}

class BaseService{
  protected model:BaseModel;
}

Now I want to implement BaseHelper and BaseService for a specific use case and assign a derived class to my property.

class MyModel extends BaseModel{
  constructor(param:string){
    super();
  }
}

class MyService extends BaseService {
  model = MyModel;  
}

However, this gives me the error Type 'typeof MyModel' is not assignable to type 'BaseModel'.

Important: I want to attach the class MyModel, not an instance of the class MyModel!


回答1:


You need to instantiate MyModel using the new keyword (new MyModel()).
You assigned the actual class (model = MyModel) instead of an instance of it.

Also, you might want to make BaseService generic:

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());
    }
}

(code in playground)


Edit

If you need the class and not the instance, then something like:

class BaseModel {}

type BaseModelConstructor = { new(): BaseModel };

class BaseService {
    protected modelCtor: BaseModelConstructor;
}

class MyModel extends BaseModel {}

class MyService extends BaseService {
    modelCtor = MyModel;  
}

(code in playground)

Or you can use generics here as well:

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;  
}

(code in playground)


If your derived classes have different ctor signatures then you can either deal with it in the base ctor type:

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

Here you can pass any count and kind of parameters, but you can also supply different signatures:

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

But you can also use a different type per derived class:

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



回答2:


model should be an instance of MyModel:

class MyModel extends BaseModel{}

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



回答3:


Use instance of BaseModel

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


来源:https://stackoverflow.com/questions/38540956/assigning-child-class-to-a-parent-class-typed-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!