程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了为什么在泛型上使用 InstanceType 是错误的大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决为什么在泛型上使用 InstanCEType 是错误的?

开发过程中遇到为什么在泛型上使用 InstanCEType 是错误的的问题如何解决?下面主要结合日常开发的经验,给出你关于为什么在泛型上使用 InstanCEType 是错误的的解决方法建议,希望对你解决为什么在泛型上使用 InstanCEType 是错误的有所启发或帮助;

为什么在泛型上使用 InstanCEType 是错误的?是协变的还是逆变的?

interface Ctor {
  new(): Instance;
}

interface Instance {
  print(): voID;
}

function f1<T extends Ctor>(ctor: T) {
  // Error: Type 'Instance' is not assignable to Type 'InstanCEType<T>'
  const ins: InstanCEType<T> = new ctor();
  ins.print();
}

function f2(ctor: Ctor) {
  // No error
  const ins: InstanCEType<Ctor> = new ctor();
  ins.print();
}

Playground Link

解决方法

这是我认为的问题:Typescript 通过查看 new ctor() 的类型(即 ctor)来确定表达式 T 的编译时类型,检查 { {1}} 必须有一个构造函数签名(确实如此),然后找到 T 的构造函数签名返回的内容。但是 T 可以是 T 的任何子类型,因此它的构造函数签名可以返回 Ctor 的任何子类型。

在这种情况下,编译器可以做两件合理的事情:

  • 要么发明一个新的类型变量(我们称之为Instance),并让表达式R extends Instance的类型为new ctor()
  • 或者只是让表达式的类型为 R

Typescript 做后者,也许是因为 Typescript 只有在你告诉它的情况下才会创建类型变量;它从不隐含地这样做。这使表达式的类型比赋值给 Instance 以进行类型检查所需的类型更弱,因为 InstanCEType<T> 确实 显式地创建了一个类型变量 InstanCEType<T>(使用 {{ 1}} 子句),可以是 R 的任意子类型。

所以表达式 infer 的类型是 Instance,但是赋值目标的类型注解是(不是真的,而是某种意义上)一个类型变量 {{1 }} 可以是 new ctor() 的任何子类型,因此存在类型错误。

一个可能的解决方案是为返回类型显式创建一个类型变量,如下所示:

Instance

也就是说,只有当您的函数以其他方式处理 R 时才值得这样做,例如具有涉及 Instance 的返回类型。否则,您使用 function f1<R extends Instance,T extends {new(): R}>(ctor: T) { const ins: R = new ctor(); ins.print(); } 的代码必须适用于 R 的任何实现,包括 R 本身,因此无论如何您也可以将其类型声明为 ins。 (同样,如果您的函数没有在其他任何地方使用 R,您不妨改为将参数类型设为 Instance)。

,

因为你说 T 扩展了 Ctor,这意味着它不完全是一个 Ctor。它可能有一个返回 Instance|Instance2 的 new。打字稿无法知道。而且由于 Ctor 声明它总是从它的构造函数返回一个实例,它不知道正确派生的正确类型。

如果您希望它与泛型和派生类型一起使用,您需要允许它使用泛型参数推断派生类型。

interface Ctor<Tinstance extends Instance> {
  new(): Tinstance;
}

interface Instance {
  print(): void;
}

function f1<Tinstance extends Instance>(ctor: Ctor<Tinstance>) {
  const ins: Tinstance = new ctor();
  ins.print();
}

大佬总结

以上是大佬教程为你收集整理的为什么在泛型上使用 InstanceType 是错误的全部内容,希望文章能够帮你解决为什么在泛型上使用 InstanceType 是错误的所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:是错误的