In TypeScript, the instanceof
operator checking the type of an object at runtime. It determines whether an object is an instance of a particular class or constructor function. It returns true
if the object is an instance of the checked type, and false
otherwise, thus improving the type safety and code clarity.
const today = new Date();
if(today instanceof Date) {
// do some work
}
1. Syntax
The general syntax to use instanceof operator is:
const result = object instanceof class;
if(object instanceof class) {
// use object
}
Here, object
is the object being checked, and class
is the class or constructor function being tested against.
2. Using InstanceOf with a Class
The instanceof
operator checks whether an object is an instance of a particular class. Note that the classtype can be an inbuilt default provided by TypeScript or a custom class.
In the following example, the today is a TypeScript Date object. And, all objects are subtypes of Object also, so both type checks produce the result as true.
const today = new Date();
console.log(today instanceof Date); // Output: true
console.log(today instanceof Object); // Output: true
Similarly, we can use the instanceof operator with custom types and user-defined classes as well:
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sound(): void {
console.log(`${this.name} says hello!`);
}
}
//Create Object
const max = new Animal("Max");
console.log(max instanceof Animal); // Output: true
console.log(max instanceof Object); // Output: true
3. Using InstanceOf with an Array
The instanceof operator works well with the Array types as well. We can use the operator to determine if an array variable is of type Array (or Object which is superclass to all objects).
const numbers = [1, 2, 3];
console.log(numbers instanceof Array); // Output: true
console.log(numbers instanceof Object); // Output: true
4. Using InstanceOf with an Interface
As we learned in the TypeScript Interface vs. Class, interfaces are only for abstraction and type checking, so they are discarded from the generated Javascript files. They exist only in the source code files, but not in the generated ‘.js‘ files.
This is why we cannot use the ‘instanceof‘ operator with the interfaces because interfaces are not preserved at runtime. It fails with the error: ‘object only refers to a type, but is being used as a value here‘.
interface Shape {
area(): number;
}
class Circle implements Shape {
constructor(private radius: number) {}
area(): number {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle instanceof Circle); // Output: true
console.log(circle instanceof Shape); // Error: 'Shape' only refers to a type, but is being used as a value here.
Workaround of Using instanceof with Interfaces
We can use type guards to achieve type checking with interfaces. Type guards are expressions that help to narrow down the type of a variable within a certain block of code. You can consider it as adding manual checks for type checking based on explicit logic and comparisons.
For example, leys say that we will assume an object to be a Shape if it has a function named area(). Then we can write the type guard as follows:
function isShape(obj: any): obj is Shape {
return typeof obj.area === 'function';
}
Now we can use this type guard method to determine if an object is instanceof an interface.
const circle = new Circle(5);
console.log( isShape(circle) ); // Output: true
5. Conclusion
As discussed in the TypeScript tutorial that the instanceof
operator is a capable way for runtime type checking. It works effortlessly simple with the class and array types (inbuilt and custom). It does not play well for interfaces but that can also be solved with the type guards.
Happy Learning !!
Comments