尝试返回扩展类的InstanceType时错误
因此,这是我的代码
class Base {
constructor (public name : string) {}
}
class Extended extends Base {
get manged_name () {
return this.name;
}
}
function GENERATE<T extends typeof Base> (Model : T) : InstanceType<T> {
const instance = new Model("something");
return instance;
}
GENERATE(Extended);
注意:生成
已经大大简化了例如,
我获得的错误是type'base'不能分配给'instanceType&lt; t&gt;'。
预期
我要做的是允许任何base
的子类用作参数,并返回其实例。为什么错误?
So here's my code
class Base {
constructor (public name : string) {}
}
class Extended extends Base {
get manged_name () {
return this.name;
}
}
function GENERATE<T extends typeof Base> (Model : T) : InstanceType<T> {
const instance = new Model("something");
return instance;
}
GENERATE(Extended);
note: GENERATE
has been greatly simplified for example purposes
The error I get is Type 'Base' is not assignable to type 'InstanceType<T>'.
Expected
What I'm trying to do is allow any child classes of Base
to be used as a parameter, and for its instance to be returned. Why is it erroring?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在您的
generate()
函数中,推断的类型<代码>新模型(“某物”)
只是base
。这是因为访问 generic 构造函数将构造函数减少到其约束中。参见 ms/ts#47502 用于源。因此,编译器不是特定于t
而不是特定于t
,而是将实例键入到base
。此外,由于类型是作为条件类型
代码> t 在
generate()
函数的主体内键入 generic 键入参数,它使instanceType&lt; t&gt;
是一个有条件的类型,它取决于通用类型参数。而且,lass,打字稿编译器无法真正验证任何可以分配给此类类型的内容。它们本质上是编译器的不透明。请参阅 Microsoft/typescript#48234 , Microsoft/typescript#48746 毫无疑问,还有许多其他来源。这意味着您正在尝试将太宽的类型
base
分配给不透明类型instanceType&lt; t&gt;
,并且失败了。如果我们希望编译器能够遵循您的逻辑,我建议您进行重构,以便通用类型参数对应于实例类型而不是构造函数类型,例如:请注意
Model 给出了一个构造签名,该签名在调用时返回类型
t
。这意味着新模型(“某物”)
产生类型t
的值,这正是我们想要的。Playground link to code
Inside your
generate()
function, the inferred type ofnew Model("something")
is justBase
. That's because accessing the construct signature on a generic constructor reduces that constructor to its constraint. See ms/TS#47502 for a source. So instead of being specific toT
, the compiler has widened the instance type all the way toBase
.Furthermore, since the
InstanceType<T>
utility type is implemented as a conditional type like this:and since the
T
type inside the body of yourgenerate()
function is a generic type parameter, that makesInstanceType<T>
a conditional type that depends on a generic type parameter. And, alas, the TypeScript compiler can't really verify that anything is assignable to such types. They are essentially opaque to the compiler. See microsoft/TypeScript#48234, microsoft/TypeScript#48746 and undoubtedly many others for a source for that.That means you are trying to assign the too-wide type
Base
to the opaque typeInstanceType<T>
, and it fails. If we want the compiler to be able to follow your logic, I'd recommend refactoring so that the generic type parameter corresponds to the instance type instead of the constructor type, like this:Note how the
Model
parameter is given a construct signature which returns typeT
when called. Meaning thatnew Model("something")
produces a value of typeT
, which is just what we want.Playground link to code