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

问题描述 投票:0回答:1

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

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

在这种情况下,我想推断用户从

initialize
方法返回的内容,并在同一类的属性中使用该类型。此
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
方法(从
initialize
扩展)推断
Base
类型,并将此类型应用于
prop

有什么想法可以做到吗?

提前致谢。

typescript types typescript-typings
1个回答
0
投票

您可以使用多态

this
类型来表示
AbstractClass
的“当前”子类的类型。然后我们可以说
prop
的类型是
initialize
this
方法的返回类型:

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

请注意,

ReturnType<this["initialize"]>
正在使用
ReturnType
实用程序类型
从函数类型中提取返回类型,并使用索引访问类型来查找
initialize
中的
this
属性的类型。

让我们测试一下:

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
  }
}

看起来不错。在每种情况下,

prop
都被赋予类型
ReturnType<this["initialize"]>
,对于
UserClass1
来说,它只能分配给
Base
,而对于
UserClass2
来说,它可以分配给
Child

Playground 代码链接

© www.soinside.com 2019 - 2024. All rights reserved.