typescript-generics - TypeScript:工厂方法 - 不正确的扩展,返回的类型不兼容
问题描述
再次花费太多时间在正确的类型上,并且想知道这样的事情是否可能没有编译器抛出不正确的基类扩展的错误,即使它正确识别返回的类型(见最后一行):
class Parent {
static create<T extends Parent>(Cls: new () => T): T {
return new Cls();
}
}
class Child extends Parent {
static create() {
return super.create(Child);
}
}
const inst = Child.create(); // correct type of "Child"
抛出的错误:
Class static side 'typeof Child' incorrectly extends base class static side 'typeof Parent'.
The types returned by 'create(...)' are incompatible between these types.
Type 'Child' is not assignable to type 'T'.
'Child' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Parent'.
如何告诉编译器,返回的类型将与 Cls 参数的类型相同?我是 TS 的新手,但我会说我不需要泛型,因为我将创建的对象的类型作为参数传递,所以我确切地知道类型。
解决方案
在这里,TypeScript 编译器试图匹配这两种static
方法。即使您确保返回类型匹配,Typescript 也不确定。你可以这样想,每次不同的调用Parent::create
都会在Parent
. 其中一个为Child
延伸Parent
,但可能AnotherChild
从 延伸Parent
。并且Child
不能分配给其他子类型,这就是编译器抱怨的原因。
我相信删除通用代码并执行以下操作会更容易 -
class Parent {
static create(Cls: new () => Parent): Parent {
return new Cls();
}
}
class Child extends Parent {
static create() : Child {
return super.create(Child);
}
}
const inst = Child.create(); // correct type of "Child"
正如Child
已经从 扩展而来的那样Parent
,Child::create
这里现在完全有效。
推荐阅读
- python - 如何在文本中查找日期
- python - 找不到元素
- node.js - 将 nodemon 与 docker 和 docker-compose 一起使用
- javascript - 关于 JS 和列表分布的新手问题
- javascript - 条纹handleServerResponse()错误ReactJS
- python - JupyterHub - 如何创建新用户名并设置密码?
- javascript - ReferenceError:自我未在nodejs模块中定义
- javascript - 如何在 Wordpress 媒体模式上触发保存?
- java - 安装 JRE 8 和 Elasticsearch 7.3.1 后没有 jvm.options
- javascript - 如何定义可在所有 API 中使用的基本 url