Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript泛型:类型为';X';不可分配给类型为';T';_Typescript - Fatal编程技术网

Typescript泛型:类型为';X';不可分配给类型为';T';

Typescript泛型:类型为';X';不可分配给类型为';T';,typescript,Typescript,下面是一些typescript代码: 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

下面是一些typescript代码:

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;
}
A类{
受保护的_列表:数组;
获取列表():数组{
返回此。\u列表;
}
}
类B扩展了类A{
构造函数(){
超级();
此._list.push(新的GreenItem());
}
}
类蓝色项目{
受保护的blueItemProperty:编号;
}
类GreenItem扩展了BlueItem{
受保护的greenItemProperty:编号;
}

编译器说“类型为“GreenItem”的参数不能分配给类型为“T”的参数。解决此问题的正确方法是什么?

解决此问题的简单方法是使列表项的构造函数也“通用”:

ClassB扩展了ClassA
{
构造函数(listItemCtor:{new():T})
{
超级();
const t=新的listItemCtor();
这个._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;
  }
}
A类
{
受保护的_列表:数组;
}
类B扩展了类A
{
构造函数()
{
超级();
此._list.push(新的GreenItem());
}
获取列表():数组
{
返回此。\u列表;
}
}

您不会有太大的松懈,因为您仍然需要对ClassB的公共属性进行类型检查。
\u list
是内部的。

解决此问题的简单方法是使列表项的构造函数也“通用”:

ClassB扩展了ClassA
{
构造函数(listItemCtor:{new():T})
{
超级();
const t=新的listItemCtor();
这个._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;
  }
}
A类
{
受保护的_列表:数组;
}
类B扩展了类A
{
构造函数()
{
超级();
此._list.push(新的GreenItem());
}
获取列表():数组
{
返回此。\u列表;
}
}

您不会有太大的松动,因为您仍然需要对ClassB的公共属性进行类型检查。
\u列表
是内部的。

绿色项
转换为
T

class ClassB<T extends GreenItem = GreenItem> extends ClassA<T> {
    constructor() {
        super();
        this._list.push(<T>new GreenItem());
    }
}
ClassB扩展了ClassA{
构造函数(){
超级();
此._list.push(新的GreenItem());
}
}

绿色项目投到
T

class ClassB<T extends GreenItem = GreenItem> extends ClassA<T> {
    constructor() {
        super();
        this._list.push(<T>new GreenItem());
    }
}
ClassB扩展了ClassA{
构造函数(){
超级();
此._list.push(新的GreenItem());
}
}

问题在于您无法在类中生成正确的类型(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> {
}
A类{
受保护的_列表:数组;
获取列表():数组{
返回此。\u列表;
}
}
类B扩展了类A{
}
类C扩展了类B{
}

但是,这里您需要检查列表中的项目是否为正确的类型。

问题在于您无法生成正确的类型(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> {
}
A类{
受保护的_列表:数组;
获取列表():数组{
返回此。\u列表;
}
}
类B扩展了类A{
}
类C扩展了类B{
}


但是,这里您需要检查列表中的项目是否为正确的类型。

设计中存在一些漏洞-您试图推动
GreenItem
以列出潜在的
RedItem[]
where
RedItem
派生自
GreenItem
ClassB是泛型的。它包含一个T数组,可以是任何类型,只要该类型扩展了GreenItem。因此T可以是,例如,LighGreenItem。因此,该数组应该只包含LighGreenItem类型的元素。但是您试图将一个GreenItem推到内部。GreenItem不是LighGreenItem。谢谢,我理解这个问题,但是有没有一种方法可以在不重写_list和get list()的情况下解决这个问题在ClassB和所有其他扩展ClassA的类中,类型设置为GreenItem/SomeOtherItem?为什么
ClassB
是泛型的?只需将其定义为
ClassB扩展ClassA
如果我想要扩展ClassB的ClassC,并且列表应该是RedItem类型呢?设计中有一些漏洞-您试图将
GreenItem
推到list潜在类型为
RedItem[]
where
RedItem
派生自
GreenItem
ClassB是泛型的。它包含一个T数组,可以是任何类型,只要该类型扩展了GreenItem。因此T可以是,例如,LighGreenItem。因此,该数组应该只包含LighGreenItem类型的元素。但是您试图将一个GreenItem推到内部。GreenItem不是LighGreenItem。谢谢,我理解这个问题,但是有没有一种方法可以在不重写_list和get list()的情况下解决这个问题在ClassB和所有其他扩展ClassA的类中,类型设置为GreenItem/SomeOtherItem?为什么
ClassB
是泛型的?只需将其定义为
ClassB扩展ClassA
如果我希望扩展ClassB的ClassC和_列表应该是RedItem类型呢?我希望最终用户不必担心类型,这样他就可以简单地执行新的ClassB()。当引入默认泛型时,我希望这是可能的。假设我有10个不同的列表,使用这种方法,用户将通过所有参数打破他的脖子。然后剩下的选项是从基类中删除泛型。请参阅我的更新。谢谢,但这不能解决它-在ClassA中,我希望列表为蓝色Item[]类型。而且,如果我有扩展ClassB的ClassC,我将再次面临这个问题。我认为你有点滥用泛型。如果你有这样的嵌套类层次结构,你应该考虑创建corr