【问题标题】:Assigning child class to a parent class typed property将子类分配给父类类型的属性
【发布时间】:2016-07-23 10:56:36
【问题描述】:

我确实有以下 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 类的实例!

【问题讨论】:

    标签: javascript inheritance typescript


    【解决方案1】:

    您需要使用 new 关键字 (new MyModel()) 实例化 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 签名,那么您可以在基本 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 };
    

    【讨论】:

    • 我刚刚更新了我的问题:我想分配一个类,而不是一个类实例
    • 我仍然收到错误:“MyService”类错误地扩展了基类“BaseService”。属性“模型”的类型不兼容。类型 'typeof MyModel' 不可分配给类型 'new () => BaseModel'。
    • @shacki 我提供的代码不会产生错误(查看指向操场的链接),这意味着您的实现会导致错误。请使用新代码更新您的问题。
    • 好的,明白了。我刚刚更新了我的问题。 MyModel 的构造函数具有附加参数,因此具有不同的调用签名。在构造函数中具有任意附加参数的最优雅的方法是什么?
    • @shacki 在这种情况下,很难为一般问题提供优雅的解决方案,这取决于您实际在做什么(与您的示例相反)。我用几种方法更新了我的答案。
    【解决方案2】:

    model 应该是MyModel 的一个实例:

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

    【讨论】:

    • 我刚刚更新了我的问题:我想分配一个类,而不是一个类实例
    【解决方案3】:

    使用 BaseModel 的实例

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

    【讨论】:

    • 我刚刚更新了我的问题:我想分配一个类,而不是一个类实例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多