type Bird = { fly: () => "fly" };
type Insect = { annoy: () => "annoy" };
type Dog = { beTheBest: () => "dogdogdog" };
type Animal = Bird | Insect | Dog;
const isBird = (animal: Animal): animal is Bird => {
if ("fly" in animal) return true;
return false;
};
const isInsect = (animal: Animal): animal is Insect => {
if ("annoy" in animal) return true;
return false;
};
const hasWings = (animal: Animal) => {
if (isBird(animal)) return true;
if (isInsect(animal)) return true;
return false;
};
The author is trying to create a composite type-guarding function named hasWings
by combining the existing isBird
and isInsect
guards. However, TypeScript fails to infer that hasWings
is also acting as a type guard. The author is exploring ways to explicitly specify this without manually restating the criteria each time.
// One suggestion is to define the return type explicitly:
const hasWings = (animal: Animal): ReturnType<typeof isBird> & ReturnType<typeof isInsect> => {
if (isBird(animal)) return true;
if (isInsect(animal)) return true;
return false;
};
// Another approach is to manually list out the criteria:
const hasWings = (animal: Animal): animal is Insect | Bird => {
if (isBird(animal)) return true;
if (isInsect(animal)) return true;
return false;
};