26
loading...
This website collects cookies to deliver better user experience
Animal
that can be either Human or Dog, and we want to implement a speak function:type Human = { talk: () => void }
type Dog = { bark: () => void }
type Animal = Human | Dog;
function speak(animal: Animal) {
// if human -> talk
// if dog -> bark
}
function speak(animal: Animal) {
if (animal.talk) {
animal.talk()
} else {
animal.bark()
}
}
animal.talk
is an invalid access of a property since Animal may be Dog or Person, and a Dog cannot talk.is
syntax:function isHuman(animal: Animal): animal is Human {
return !!animal.talk
}
true
, the type predicate will be true and TS will understand that animal is a Human subtype of Animal. function speak(animal: Animal) {
if (isHuman(animal)) {
animal.talk()
} else {
animal.bark()
}
}
animal.talk
can be either Dog or Human within the type guard. And so to solve it we can cast animal as Human
within the type guard:function isHuman(animal: Animal): animal is Human {
return !!(animal as Human).talk
}
function isHuman(animal: Animal): animal is Human {
return 'talk' in animal;
}
type Human = { name: string; talk: () => void }
type Dog = { name: string; bark: () => void }
type Animal = Human | Dog;
function isHuman(animal: Animal): animal is Human {
return 'talk' in animal;
}
function speak(animal: Animal) {
if (isHuman(animal)) {
animal.talk()
} else {
animal.bark()
}
}
Thanks to @jazlalli1 for this suggestion! ↩