Typescript - 来自各种接口列表的数组项

Typescript - array items from a list of various interfaces

interface NamedAnimal {
  name: string;
}

interface Fish extends NamedAnimal {
  type: 'fish';
  water: 'fresh' | 'salt';
}

interface Dog extends NamedAnimal {
  type: 'dog';
  breed: 'terrier' | 'mutt';
}

type Animal = Fish | Dog;

const animals: Animal[] = [
  { type: 'dog', name: 'rover', breed:'terrier' }
];


function doSomething(animal: Animal) {
  if (animal.breed) {
    // do something doglike.....
  }
}

doSomething(animals[0]);

在上面的例子中,为什么引用 'animal.breed' 给我一个错误 'Property "breed" does not exist on type Fish'

我如何更改它,使其可以是列出的任何类型?

(这不是我的实际代码,而是我遇到的问题的示例)。

Type assertation 会帮助你。 您可以指定在特定情况下要使用的类型。

function doSomething( animal: Animal ) {
   if((animal as Dog).breed) {
      // do something doglike.....
   }
}

您可以使用 in 运算符将类型缩小到 Dog,请参阅 TypeScript documentation

function doSomething(animal: Animal) {
  if ('breed' in animal) {
    // do something doglike.....
  }
}

由于 FishDog 都有一个 type 字段,您也可以使用此字段来区分类型:

function doSomething(animal: Animal) {
  if (animal.type === 'dog') {
    // TypeScript now know this is the 'Dog' type
    console.log(animal.breed)
  }
}