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

时间:2016-07-23 10:56:37

标签: javascript inheritance typescript

我确实有以下2个基本条款:

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类的实例!

3 个答案:

答案 0 :(得分:1)

model应该是MyModel的实例:

class MyModel extends BaseModel{}

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

答案 1 :(得分:1)

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

此外,您可能想要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

修改

如果你需要这个类而不是实例,那么就像:

class BaseModel {}

type BaseModelConstructor = { new(): BaseModel };

class BaseService {
    protected modelCtor: BaseModelConstructor;
}

class MyModel extends BaseModel {}

class MyService extends BaseService {
    modelCtor = MyModel;  
}

code in playground

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

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

如果您的派生类具有不同的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 };

答案 2 :(得分:0)

使用BaseModel的实例

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