【问题标题】:Class decorator, how to make sure the class is extending and implementing other classes类装饰器,如何确保该类正在扩展和实现其他类
【发布时间】:2018-05-25 12:50:07
【问题描述】:

对不起,这个奇怪的标题,我不太知道如何用一句话来描述我想做的事情。

我必须定义一堆类,它们都将从这个类扩展并实现另一个类。

class SoulCoughing extends Super implements BonBon { /.../ }
class MoveAside extends Super implements BonBon { /.../ }
class LetTheManGoThru extends Super implements BonBon { /.../ }

我编写了一种包装函数,用作这些类的装饰器。

const Eminem = function(klass: Constructable<????>) {
  const instance = new klass();
  // Do stuff
}

Constructable 是我正在使用的一个小接口,否则 TypeScript 会抛出关于没有构造函数的错误。

interface Constructable<T> {
  new(): T;
}

现在这是我的问题,我不知道在我的包装函数中为参数klass 分配什么类型?我试过这样做:

... function(klass: Contrusctable<Super & BonBon>)

还有这个:

... function(klass: Contrusctable<Super | BonBon>)

我也尝试像这样修改我的可构造界面:

interface Constructable<T, U> {
  new(): T & U;
}

... function(klass: Contrusctable<Super, BonBon>)

但我不断收到Argument of type 'typeof SoulCoughing' is not assignable to parameter of type 'Constructable&lt;everythingIveTriedSoFar&gt;' 错误。

所以我的问题是,我应该对参数klass 使用什么类型定义?我知道我可以只使用any,但我真的很想确保所传递的类扩展了Super 并实现了BonBon

【问题讨论】:

    标签: class typescript extends implements


    【解决方案1】:

    我猜SoulCoughing 等类实际上没有无参数构造函数,因此根本不能充当Constructable&lt;{}&gt;;最可能的罪魁祸首是Super 的构造函数有一个强制参数,这会使所有子类默认无法匹配new()。请注意,这也意味着您的 Eminem 实现可能还希望使用一些参数调用 new klass(...)

    修复它的正确方法是将Constructable&lt;T&gt; 声明为具有正确参数类型的构造函数。假设Super 看起来像这样:

    class Super {
      constructor(elevator: number, mezzanine: string) {
        //...
      }
    }
    

    然后你可以定义Constructable来匹配:

    interface Constructable<T extends Super & BonBon = Super & BonBon> {
      new(chump: number, change: string): T; // same args as Super
    }
    

    Eminem 喜欢:

    const Eminem = function(klass: Constructable) {
      const instance = new klass(2, "rise");
      // Do stuff
    }
    

    最后:

    Eminem(SoulCoughing); // no error
    

    我只保留了Constructable 泛型,以防您希望 TypeScript 保留特定子类的类型,如下所示:

    const SlimShady = function <T extends Super & BonBon>(klass: Constructable<T>): T {
      return new klass(2, "fat");
    }
    
    // returns same type as passed-in constructor
    const cutLean: MoveAside = SlimShady(MoveAside);
    

    好的,希望对您有所帮助;祝你好运!

    【讨论】:

      猜你喜欢
      • 2021-07-07
      • 2019-06-28
      • 2019-07-20
      • 2019-01-29
      • 1970-01-01
      • 2013-01-22
      • 2016-08-18
      • 2018-05-08
      • 2019-05-17
      相关资源
      最近更新 更多