为什么在泛型上使用 InstanceType 是错误的

wea*_*nhe 7 typescript typescript-generics

为什么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();
}

Run Code Online (Sandbox Code Playgroud)

游乐场链接

Tim*_*Tim -4

因为你说 T 扩展了 Ctor,这意味着它不完全是一个 Ctor。它可能有一个返回 Instance|Instance2 的 new。Typescript 无法知道。由于 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();
}
Run Code Online (Sandbox Code Playgroud)

  • *“它可能有一个新的返回 Instance|Instance2”*这不是真的;像`{new(): Instance | 这样的类型 Instance2}` 不会扩展 `{new(): Instance}`。如果是这样,您可以将构造“Instance2”实例的事物分配给声称构造“Instance”实例的事物。 (2认同)