以下是一些打字稿代码:
class ClassA<T extends BlueItem = BlueItem> {
protected _list: Array<T>;
get list(): Array<T> {
return this._list;
}
}
class ClassB<T extends GreenItem = GreenItem> extends ClassA<T> {
constructor() {
super();
this._list.push(new GreenItem());
}
}
class BlueItem {
protected blueItemProperty: number;
}
class GreenItem extends BlueItem {
protected greenItemProperty: number;
}
编译器说&#34;类型&#39; GreenItem&#39;不能分配给&#39; T&#39;类型的参数。什么是解决这个问题的正确方法?
答案 0 :(得分:2)
解决问题的一种简单方法是使列表项的构造函数也“通用”:
class ClassB<T extends GreenItem = GreenItem> extends ClassA<T>
{
constructor(listItemCtor: {new(): T})
{
super();
const t = new listItemCtor();
this._list.push(t);
}
}
它不是通用的解决方案 - 但如果适用的话 - 它会有所帮助。
作为一个选项,你也可以在基类中完全删除泛型:
class ClassA
{
protected _list: Array<any>;
}
class ClassB<T extends GreenItem = GreenItem> extends ClassA
{
constructor()
{
super();
this._list.push(new GreenItem());
}
get list(): Array<T>
{
return this._list;
}
}
由于您仍然对ClassB的公共属性进行类型检查,因此您不会失去太多。 _list
是内部的。
答案 1 :(得分:1)
将GreenItem
投射到T
。
class ClassB<T extends GreenItem = GreenItem> extends ClassA<T> {
constructor() {
super();
this._list.push(<T>new GreenItem());
}
}
答案 2 :(得分:1)
问题是你不能在你的课程中生成正确的类型(T),因为你不知道T是什么。由于您不希望将工厂函数传递到您的类中,因此下一个最佳解决方案是使用联合类型并允许这两种类型,如下所示:
class ClassA<T = BlueItem> {
protected _list:Array<T | BlueItem>;
get list(): Array<T | BlueItem> {
return this._list;
}
}
class ClassB<T = GreenItem> extends ClassA<T | GreenItem> {
}
class ClassC extends ClassB<RedItem> {
}
但是,在这里您需要检查列表中的项目是否是正确的类型。