如何重载泛型方法,以减少Typescript中的泛型?

时间:2018-07-25 14:47:03

标签: typescript oop

我在抽象类中有一个通用的静态方法:

abstract class Base {
  static find<T extends Base>(options?: Object): Promise<T[]> {
    return findResults(options);
  }
}

我想在派生类中指定它的类型:

class Extended extends Base { 
  static find<Extended>(options?: Object): Promise<Extended[]>;
  // Error: Function implementation is missing or not immediately following the declaration.
}

Typescript是否以任何方式支持此行为?

1 个答案:

答案 0 :(得分:3)

该类型似乎违反了Extended静态方面的Liskov substitution principle。显然Extended构造函数必须是有效的Base构造函数,因此如果Base.find()可以为 any Promise<T[]>返回T扩展Base,那么Extended.find()也应该能够做到这一点。

静态方法中的泛型很奇怪,因为静态成员无法访问类的类型参数。但是也许您想要的并不是真正通用的……您希望Base.find()返回Promise<Base[]>,而Extended.find()返回Promise<Extended[]>,对吗?这听起来像是polymorphic this的激励示例。不幸 polymorphic this isn't supported for static members,至少到目前为止。

我的建议是仅手动实现您期望的关系:

abstract class Base {
  static find(options?: Object): Promise<Base[]> {
    return findResults(options); // is this some function somewhere?
  }
}

class Extended extends Base {
  // maybe not type safe 
  static find: (options?: Object) => Promise<Extended[]>;
}

请注意,我在此所做的全部工作是声明Extended.find()返回一个Promise<Extended[]>,而不会从Base.find()更改其实现。除非Base.find()的实现足够聪明地知道如何执行此操作,否则这可能不是类型安全的。我对此表示怀疑,所以要小心。您可能想以其他方式实施它:

class Extended extends Base {
  static find(options?: Object): Promise<Extended[]> {
    // change the implementation in a way that constrains the results,
    // maybe with a type guard somewhere
  }
}

好的,希望能有所帮助。祝你好运!