代码之家  ›  专栏  ›  技术社区  ›  Khanon

如何推断类方法未知的返回类型并在属性中使用它

  •  1
  • Khanon  · 技术社区  · 2 年前

    你好,我又来了一次TS冒险和头痛:)

    我正在开发一个框架,其中一些类型是未知的,因为用户可以从抽象方法返回任何内容。

    在这种情况下,我想推断用户返回的内容 initialize 方法,并在同一类的属性中使用该类型。这 初始化 方法必须返回从扩展的类 Base .

    代码如下所示:

    class Base {
      method_1() {}
    }
    
    class Child extends Base {
      method_2() {}
    }
    
    abstract class AbstractClass {
      prop: C
    
      abstract initialize(): C extends Base
    }
    
    class UserClass1 extends AbstractClass {
      initialize() {
        return new Base()
      }
    
      someMethod() {
        this.prop.method_1()  // Valid, no TS error
        this.prop.method_2()  // Error, it doesn't exist in Base
      }
    }
    
    class UserClass2 extends AbstractClass {
      initialize() {
        return new Child()
      }
    
      someMethod() {
        this.prop.method_1()  // Valid, no TS error
        this.prop.method_2()  // Valid, no TS error
      }
    }
    
    

    在简历中,我不得不推断 C 键入自 初始化 方法(扩展自 基础 )并将此类型应用于 prop .

    有什么想法可以做到吗?

    提前谢谢。

    1 回复  |  直到 2 年前
        1
  •  2
  •   jcalz    2 年前

    您可以使用 the polymorphic this type 表示的“当前”子类的类型 AbstractClass 。然后我们可以这么说 prop 的类型是的返回类型 initialize 的方法 :

    abstract class AbstractClass {
      prop!: ReturnType<this["initialize"]>
      abstract initialize(): Base
    }
    

    请注意 ReturnType<this["initialize"]> 正在使用 the ReturnType utility type 从函数类型中提取返回类型,以及 indexed access type 查找的类型 初始化 中的属性 .

    让我们测试一下:

    class UserClass1 extends AbstractClass {
      initialize() {
        return new Base()
      }
    
      someMethod() {
        this.prop.method_1()  // Valid, no TS error
        this.prop.method_2()  // Error, it doesn't exist in Base
      }
    }
    
    class UserClass2 extends AbstractClass {
      initialize() {
        return new Child()
      }
    
      someMethod() {
        this.prop.method_1()  // Valid, no TS error
        this.prop.method_2()  // Valid, no TS error
      }
    }
    

    看起来不错。在每种情况下, 道具 给定了类型 ReturnType<这个[“初始化”]> ,用于 UserClass1 已知只能分配给 Base ,而对于 UserClass2 已知可分配给 Child .

    Playground link to code

    推荐文章