How to define what type does belong argument in function if it's type can be a custom type Dog | Cat

type Cat = {
    name: string,
    meow: () => string,
}

type Dog = {
    name: string,
    bark: () => string,
}

const cat: Cat = {
    name: 'Pushok',
    meow: () => 'meow!'
};

const dog: Dog = {
    name: 'Bobik',
    bark: () => 'bark!',
}

function isDog(value: {bark(): string}): value is Dog {
    return value.bark() === 'bark!';
}


function isCat(value: {meow(): string}): value is Cat {
    return value.meow() === 'meow!';
}

export function whatDoesThePetSay(pet: Cat | Dog): string {
// firstly i need to define what type pet is and then do functions below
    if (isCat(pet)) {
        pet.meow()
    }
    if (isDog(pet)) {
        pet.bark()
    }
}

console.log(whatDoesThePetSay(cat));
console.log(whatDoesThePetSay(dog));

I mean, I would define the animals better, and call them all Animals, which has a function noise, but…

this is superfluous; the pet was either a Cat or a Dog. If it’s not a cat, its a dog, so you could just make that an else.

You could also forego the isCat and isDog functions and instead use the actual instanceof operator.
if(pet instanceof Cat) { //its a cat. } else { //it was a dog. }

This is rather tricky. If you ever add another animal, they will always default to cat. I like to keep it more defensive, something like:

if (pet instanceof Dog) {
   // do something
}

if (pet instanceof Cat) {
  // do something else
}

throw new TypeError(`Unable to determine what pet says. Unknown pet type "${typeof pet}".`);

note that that will not work unless the “do this” contains a return

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.