带联合的条件类型

时间:2019-01-23 14:41:05

标签: javascript typescript

我正在合并两个包含不同类型数据的数组。使用这两种类型的并集,它看起来像这样:

interface Animal {
  animalid: number;
  species: string;
}

interface Person {
  personid: number;
  name: string;
}

const animals: Animal[] = getAnimals();
const people: Person[] = getPeople();

const bothThings: (Animal|Person)[] = [...animals, ...people];

我希望能够调用传入动物或人的id的函数,但是id的类型不同,分别取决于animalidpersonid的类型。我可以确定需要哪个属性,因此可以基于id属性确定它的类型,但是由于出现TypeScript错误而无法使用它:Property 'animalid' does not exist on type 'Animal|Person'. Property 'animalid' does not exist on type 'Person'.

const indexOfThing: number;
let id: number;

...

if (bothThings[indexOfThing].hasOwnProperty('animalid')) {
  id = bothThings[indexOfThing].animalid // TypeScript Error
} else if (bothThings[indexOfThing].hasOwnProperty('personid')) {
  id = bothThings[indexOfThing].personid // TypeScript Error
}

functionThatNeedsId(id);

如何根据条件正确设置类型,或者有更好的方法来实现此目的?

谢谢

2 个答案:

答案 0 :(得分:3)

混淆之处在于,尽管您在运行时使用hasOwnProperty缩小了类型的范围,但实际上并没有在编译时这么做,因此编译器会抱怨。

您可以使用type guards

解决此问题

如果您执行以下操作,则可能会起作用:

const animals: Animal[] = getAnimals();
const people: Person[] = getPeople();

function isAnimal(animalOrPerson : Animal|Person) : animalOrPerson is Animal {
    return (object as Animal).animalid !== undefined;
} 

function isPerson(animalOrPerson  : Animal|Person) : animalOrPerson is Person {
    return (object as Person).personid!== undefined;
} 


const bothThings: (Animal|Person)[] = [...animals, ...people];

if (isAnimal(bothThings[indexOfThing])) {
  id = bothThings[indexOfThing].animalid 
} else if (isPerson(bothThings[indexOfThing].hasOwnProperty('personid'))) {
  id = bothThings[indexOfThing].personid 
}

这样做可以使编译器在条件内正确确定对象的实际类型。

答案 1 :(得分:1)

尝试这个:

webdriver.Firefox()