泛型作为成员或变量使用时为什么要指定泛型

Why do I have to specify generic type when it is used as a member or variable

我以下面的class为例:

export abstract class AbstractSomething<T extends SomethingElse, V> { }

我还有以下 2 个扩展 classes:

export class A extends AbstractSomething<TypeThatExtendsSomethingElse, string> { }
export class B extends AbstractSomething<OtherTypeThatExtendsSomethingElse, boolean> { }

现在在第三个不相关的 ServiceClass class 我有一个成员是 AbstractSomething 的数组(数组中的每个项目可以是 A 或 B):

export class ServiceClass {
    public array: AbstractSomething[];
}

以上代码给出如下错误:Generic type 'AbstractSomething' requires 2 type arguments.

我想弄清楚为什么会出现此错误?上面的代码在 Java 中运行良好。我的成员可以是任何通用类型,而不仅仅是特定类型。我也许可以使数组类型 AbstractSomething<any, any>[] 但这不正确,因为第一个泛型类型扩展 SomethingElse.

为什么会出现此错误,可能的解决方案是什么?

确实,您应该显式传递通用参数,但可以 AbstractSomething<SomethingElse, unknown> 而不是 any。在这种情况下,您告诉编译器第一种类型是 SomethingElse 或其任何后代,第二种类型是未知的。 unknown 类型比 any 更安全,请参阅 difference

您还可以为泛型类型分配默认值,在这种情况下您可以跳过类型并使用默认值,例如:

export class AbstractSomething<T extends SomethingElse = SomethingElse, V = unknown> { }
const arr: AbstractSomething[] = [];

如果数组可能只包含AB项,最好将其定义为Array<A | B>,这种类型比较冗长,可以这样使用:

const arr = new Array<A | B>();
...
const item = arr[0];
if (item instanceof A) {
  // do something with A
} else {
  // the compiler knows that the item has B type
}