Typescript Instanceof Type Guard

instanceof is an operator in TypeScript, which checks if an object is an instance of a specific class or a constructor function. The Instanceof also takes inheritance into account. It returns true if the object inherits from the class’s prototype. instanceof also acts as a Type Guard, helping us infer the type correctly in the scope.

Using InstanceOf

We use the InstanceOf operator between the instance and the type want to test. For Example

It returns true if the obj is an instance of the class, or it appears anywhere in the inheritance chain. Else it will return false.

For example

Please note that person prototypically inherits from Object, Hence it returns true

It works for most of the types including arrays, functions, RegExp etc

But it will not work on primitive types. It will result in both compile-time and run-time errors.

The left-hand side of an ‘instanceof’ expression must be of type ‘any’, an object type, or a type parameter.

Inheritance

In the above examples, we saw that person instanceof Object also returns true.  i.e because person prototypically inherits from Object

To understand let us consider the following example. We have four classes here. Person is the base class. The Employee and Customer extends from the Person class. The SalesPerson class extends the Employee class.

As you can see from the above result. the employee class return true for both Employee & Person class as Employee inherits from the Person class. Similarly, salesPerson class is inherited from the Employee class, which in turn inherits from the Person class. Hence it returns true for both Employee & Person.

InstanceOf As Type Guard

Consider the following classes. Customer & SalesPerson. Both extend the Person class. Both classes have the common method code().They also have additional methods buy() (Customer class) and sell() (SalesPerson class)

The following getCode retrieves the code, which is present in both the classes. We will call the getCode method passing the newly created Customer instance. But Since we are using the Person as the function argument, this code will result in a compiler error Property 'code' does not exist on type 'Person'

The one way to solve the problem is to use the converting the obj into any as shown below. But using the any is not an ideal solution.

This is where the instanceOf is becomes useful. We can use it to check the type and also infer the type in the block where InstanceOf it is used.

Now, as you can see from the image below.

Outside the if block, the intellisense shows only one property name, which is from the Person class.

Inside the (obj instanceOf customer) block, the typescript correctly infers the type as Customer, It shows the method Buy But does not show the method Sell

While inside the (obj instanceOf SalesPerson) block it infers the type as SalesPerson. Here it shows the method Sell and does not show Buy.

TypeScript InstanceOf Type Guard
TypeScript InstanceOf Type Guard

Hence, the following BuySell method correctly call the buy & sell methods and does not throw any errors.

In the following code, we just moved sell method from the SalesPerson to Customer & vice versa. Now the compiler throws the error. For the error message you can see that outside the loop, Typescript infers the types a Person. Inside the instanceof Customer block it treats it as Customer and inside the instanceof SalesPerson it

Typeof vs Instanceof

typeof returns data type of the identifier as a string. instance returns true/false if a value is an instance of a class or a constructor function. It also takes its inheritance into account.

The typeof operator works mainly on primitive values (number, string, boolean, bigint, symbol & undefined) except for null. The typeof returns “function” for functions and for everything else, it returns “object”. It also returns “object” for null, which is a bug. On the other hand, instanceof is applicable only to objects and does not work on primitive values.

Instanceof does not work with Types

instanceof will return true only if it matches the function from which it was constructed. It won’t tell you if a particular object is of a particular type.

For Example, in TypeScript, we can create a custom type using a type alias or interface. But these are specific to TypeScript and will be removed when code is compiled to JavaScript. Hene the type Person does not exist in JavaScript.

References

Instanceof narrowing

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top