Typescript访问扩展的Class变量

问题描述

我的代码

我有一个“ Item”类,该类由具有自己变量的其他类扩展,例如:

class Item {
  name: string
  symbol: string
  constructor(n: string,s: string){
    this.name = n
    this.symbol = s
  }
}

class Food extends Item {
  type: string
  constructor(n: string,s: string,t: string){
    super(n,s)
    this.type = t
  }
}

class Jewelry extends Item {
  value: number
  constructor(n: string,v: number){
    super(n,s)
    this.value = v
  }
}

我这样初始化:

let items: Array<Food | Jewelry> = []

items.push(new Food('Carrot','C','vegetable'))
items.push(new Jewelry('Necklace','N',100))

问题:

现在,当我键入items [0] .type时,编辑器无法识别子类“ food”特定的变量“ type”,而只能识别父变量“ name”和“ symbol”。当然与子类“珠宝”相同。

它抛出了这个错误

Property 'type' does not exist on type 'Food | Jewelry'.
  Property 'type' does not exist on type 'Jewelry'.ts(2339)

如果我像这样隐式设置索引,它将按预期工作:

items[0] = new Food('Carrot','vegetable')

items[0].type // => 'vegetable'

即使通过“ push()”方法添加对象,我也可以访问子类变量吗?

感谢您的帮助!

欢呼

西蒙

解决方法

问题在于,编译器不知道哪个对象属于数组中的哪种类型。它不知道FutureBuilderitems[0],而Fooditems[1]。它只知道在某种程度上都是Jewelry,所以您可以安全键入的全部是Item,因为这是唯一的通用属性。

但是,您可以稍微支持编译器。例如,通过检查对象属于哪个类,然后使用该附加类型安全性。

在下面的示例中,我使用item[x].name来实现这一目标,并且编译器现在没有抱怨要访问instanceof对象的type和访问Food的情况。 value个对象:

Jewelry