typescript - 在 TypeScript 中返回抽象类中的子类
问题描述
我已将问题简化为以下情况:
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
耶,错误解决了!但是我也想在this
里面Foo
使用我使用的相同方式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 知道相信我们它实际上是相同的,但是由于我在预期this
的上下文中使用了大量代码C
,这是我宁愿不做的事情。
编辑:我没有使用基类,而是开始使用一些包含共享功能的函数:
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 个这样的函数,我觉得让这些方法直接调用函数的样板可以被基类替换,但后来我遇到了这个问题。
解决方案
您正在与打字稿的类型检查作斗争。
总是有它的hacky方式。any 类型可用于返回 C:
return this as any
Typescript 正在做预期的事情,并保护您免受自己的伤害。将对象强制放入扩展类会导致数据丢失,因此您需要向编译器展示您知道这一点。
推荐阅读
- java - 使用 UWC java regex 将 Mediawiki 迁移到 Confluence 无法与在线 |thumb 匹配
- android - 工具栏子节点不居中
- javascript - 使用Jquery或JS在html表中查找列的总和
- angular - 无论初始路由器端点如何,在创建角度应用程序实例时运行的服务
- regex - -v 选项在 grep 中不起作用
- swift - 调用 Swift 4 泛型方法产生错误
- java - read() 方法后的 Bufferedreader 下一行
- java - 带有@Query 的 Spring Data Jpa Projection 返回未找到转换器
- google-app-engine - 谷歌云上的 https 间歇性工作
- c# - 无法使用 AngulaJS 和 MVC C# 在服务器上重定向