你好,我又来了一次我的 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
。
有什么想法可以做到吗?
提前致谢。
您可以使用多态
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
。