How To Use InstanceOf On An Interface In TypeScript?

Tim Mouskhelichvili
Tim Mouskhelichvili
3 minutes to read

Sometimes a developer needs to check the type of a TypeScript interface at run time. Typically, the instanceOf keyword is used for those tasks.

Unfortunately, you cannot use the instanceOf keyword on an interface in TypeScript. However, there are other alternative routes that you can take to achieve a similar behavior:

  • You can create a user-defined type guard.
  • You can use a tagged union.
  • You can use a discriminated union.

This article analyses those solutions and shows how to code them with real-life TypeScript examples.

Let's get to it 😎.

typescript instanceof interface

Method #1 - Create a type guard

The first way to check the type of an interface is to create a custom type guard.

Type guards are implemented using conditional statements and such keywords as instanceOf, typeof, or in.

To implement a type guard, you must find a property unique to the interface you want to check.

For example, let's say we declare those types:

typescriptinterface IAnimal {
    name : string;
}

interface ICow extends IAnimal {
    giveMilk : () => void;
}

interface IDog extends IAnimal {
    bark : () => void
}

Read: How to extend an interface in TypeScript?

To determine if an animal is a cow or a dog, you need to create two type guards, one for the cow and one for the dog:

typescriptconst isDog = (animal: IAnimal): animal is IDog => {
    return 'bark' in animal;
}

const isCow = (animal: IAnimal): animal is ICow => {
    return 'giveMilk' in animal;
}

Those two type guards verify if the animal is a cow or a dog.

Then, we can create a function to call the animal's action based on its type:

typescriptconst doAction = (animal: IAnimal): void => {
    if (isDog(animal)) {
        animal.bark();
    }

    if (isCow(animal)) {
        animal.giveMilk();
    }
}

However, this method is not scalable since you must create type guards for each existing animal.

It is where tagged unions come into play.

Method #2 - Use a tagged union

Another method of checking the interface type involves using the tagged union type, introduced in TypeScript 2.0.

Let's rewrite the same example with tagged unions:

typescriptconst doAction = (animal: IDog | ICow): void => {
    if ('bark' in animal) {
        animal.bark();
    }

    if ('giveMilk' in animal) {
        animal.giveMilk();
    }
}

As you can see, with the union type, we can pass a dog or a cow as the animal.

The typescript compiler can then infer the correct type of the interface.

Method #3 - Use a discriminated union

Another option to check the type of an interface involves using a discriminated union.

First, you need to add a type field to all the interfaces:

typescriptinterface IAnimal {
    name : string;
}

interface ICow extends IAnimal {
    giveMilk : () => void;
    type: 'cow';
}

interface IDog extends IAnimal {
    bark : () => void
    type: 'dog';
}

Then, we can use that type to determine the type of the animal, like so:

typescriptconst doAction = (animal: IDog | ICow): void => {
    switch(animal.type) {
        case 'cow':
            animal.giveMilk();
            break;  
        case 'dog':
            animal.bark();
            break;
    }
}

Read more: The switch statement in TypeScript

Final thoughts

As you can see, although you cannot use the instanceOf keyword to check the type of an interface in TypeScript, you have many other options.

You can create a type guard or use the power of the union type to do so.

typescript instanceof interface

Here are some other TypeScript tutorials for you to enjoy:

Comments (0)
Reply to: