为什么当用作成员或变量时必须指定泛型

问题描述 投票:0回答:1

我以以下课程为例:

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

我也有以下两个扩展类:

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

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

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

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

我试图弄清楚为什么会出现此错误?上面的代码在Java中工作正常。我的成员可以是任何通用类型,而不仅仅是特定类型。我也许可以将数组类型设置为AbstractSomething<any, any>[],但由于第一个泛型类型扩展了SomethingElse,所以这是不正确的。

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

typescript oop generics abstract typescript-generics
1个回答
1
投票

实际上,您应该显式传递通用参数,但是可以代替any而是AbstractSomething<SomethingElse, unknown>。在这种情况下,您告诉编译器第一种类型是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
}
© www.soinside.com 2019 - 2024. All rights reserved.