泛型作为成员或变量使用时为什么要指定泛型
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[] = [];
如果数组可能只包含A
或B
项,最好将其定义为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
}
我以下面的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[] = [];
如果数组可能只包含A
或B
项,最好将其定义为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
}