'What is reason to use is operator in TypeScript?

What is reason to use is operator in TypeScript in this case?

type Species = "cat" | "dog";


interface Pet {
   species: Species
}

interface Cat extends Pet {

}

function petIsCat(pet: Pet): pet is Cat {
   return pet.species === "cat";
}

Why to use pet is Cat instead boolean if body returns bool type?



Solution 1:[1]

boolean is just a data type while 'is' operator is used for type-testing. Let me change your example a little bit:

type Species = 'cat' | 'dog';

interface Pet {
    species: Species;
}

class Cat implements Pet {
    public species: Species = 'cat';
    public meow(): void {
        console.log('Meow');
    }
}

function petIsCat(pet: Pet): pet is Cat {
    return pet.species === 'cat';
}

function petIsCatBoolean(pet: Pet): boolean {
    return pet.species === 'cat';
}

const p: Pet = new Cat();

p.meow(); // ERROR: Property 'meow' does not exist on type 'Pet'.

if (petIsCat(p)) {
    p.meow(); // now compiler knows for sure that the variable is of type Cat and it has meow method
}

if (petIsCatBoolean(p)) {
    p.meow(); // ERROR: Property 'meow' does not exist on type 'Pet'.
}

Of course you can use type casting:

(<Cat>p).meow(); // no error
(p as Cat).meow(); // no error

But it depends on the scenario.

Solution 2:[2]

The way I understand it is as so:

pet is Cat

  • Is the function return type.
  • because it has the "variable is type" syntax it is called a user defined type check
  • This function return type can be used by your code "type-checker" at compile time: therefore: in your code editor equipped with some type checking software for TS, it'll display 0 compile errors and will know the type of person1 after the user-define type guard:
const isPerson = (object: any): object is Person => "address" in object

interface Person {
    address: string
}
// type of person1 is {address: string}
const person1 = {
    address: "rue"
}

if(isPerson(person1)){
    console.log(person1.address) // type is Person as opposed to {address: string}
} else {
    console.log("person is not a Person")
}

Hope that helps

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Viacheslav
Solution 2 Matador