【问题标题】:How do I overload generic methods to make them less generic in Typescript?如何重载泛型方法以使它们在 Typescript 中不那么泛型?
【发布时间】:2018-07-25 14:47:03
【问题描述】:

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

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 是否以任何方式支持这种行为?

【问题讨论】:

    标签: typescript oop


    【解决方案1】:

    该类型似乎违反了Liskov substitution principle 的静态方面Extended。显然Extended 构造函数需要是一个有效的Base 构造函数,所以如果Base.find() 可以返回一个Promise&lt;T[]&gt; 用于任何 T 扩展Base,那么Extended.find() 应该也能做到。

    静态方法中的泛型很奇怪,因为静态成员不能访问类的类型参数。但也许你想要的根本不是通用的......你想要Base.find() 返回Promise&lt;Base[]&gt;,并且Extended.find() 返回Promise&lt;Extended[]&gt;,对吗?这听起来像是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&lt;Extended[]&gt;,而不更改其从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
      }
    }
    

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

    【讨论】:

    • “静态成员的多态“this”问题的第一行正是我的用例。我正在尝试扩展 TypeORM 的功能,但是有很多陷阱,因为它正在做的所有巫术魔术来猜测哪个模型对应于哪个存储库。我认为如果没有很多变通方法和技巧,我想做的事情是不可能的,但这就是生活谢谢您的回答!
    猜你喜欢
    • 2017-05-13
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    相关资源
    最近更新 更多