【发布时间】:2021-09-26 09:35:27
【问题描述】:
我已将我的问题简化为以下情况:
abstract class Foo {
child: Foo
foo(): Foo {
return this.child
}
}
class Bar extends Foo {
bar = true
}
const foo = new Bar()
// Property 'bar' does not exist on type 'Foo'. ts(2339)
foo.foo().bar
这个错误是不言自明且不足为奇的,但我想要实现的是foo() 返回子类类型的某些内容。在本例中为Bar,这样我就可以使用它的属性bar。我们可以这样实现:
abstract class Foo<C extends Foo<C>> {
child: C
foo(): C {
return this.child
}
}
class Bar extends Foo<Bar> {
bar = true
}
const foo = new Bar()
foo.foo().bar
是的,错误已解决!但是我也想在Foo 中使用this,就像我使用C 一样,即子类类型:
abstract class Foo<C extends Foo<C>> {
foo(): C {
// Type 'this' is not assignable to type 'C'.
// 'this' is assignable to the constraint of type 'C',
// but 'C' could be instantiated with a different subtype of constraint 'Foo<C>'. ts(2322)
return this
}
}
class Bar extends Foo<Bar> {
bar = true
}
const foo = new Bar()
foo.foo().bar
我们不能,因为 TypeScript 不知道作为类型参数传递的子类类型实际上与实际的子类类型相同。
有没有办法解决这个问题,这样我就不会出现这个错误?
我可以通过转换 this 来解决它,如下所示:this as unknown as C,让 TypeScript 知道相信我们它实际上是相同的,但是因为我有很多代码在 C 的上下文中使用 this意料之中,这是我宁愿不做的事情。
编辑:我开始使用一些包含共享功能的函数,而不是使用基类:
interface Foo {
child: Foo
}
function fooFn<C extends Foo>(parent: C, child: C): C {
return child
}
class Bar implements Foo {
child: Bar
bar = true
foo() {
return fooFn(this, this.child)
}
}
const foo = new Bar()
foo.foo().bar
这对我的用例很有效,但现在它变成了 20 个这样的函数,我觉得让这些方法直接调用函数的样板可以被基类替换,但后来我遇到了这个问题。
【问题讨论】:
标签: typescript typescript-generics