Summary
The instanceof
operator is designed to work with classes in JavaScript, not interfaces or type aliases.
Understanding TypeScript's Explanation
The problem arises from the fact that instanceof
is a JavaScript feature that expects a concrete value on the right side. When you use x instanceof Foo
, JavaScript checks if Foo.prototype
is in the prototype chain of x
at runtime.
However, in TypeScript, interfaces and type aliases do not have a runtime representation. Therefore, trying to use instanceof
with these constructs will result in failure, as they are purely types and not values.
TypeScript is essentially warning that this approach will never succeed, as Foo
is a type and not an actual value.
If you intended to use a class instead, as seen in other languages, classes do create runtime values. Further information on this topic is available below.
Alternative to instanceof
with Types and Interfaces
Consider exploring type guards and user-defined type guards as alternatives.
Transitioning from Interface to Class in TypeScript
While switching from an interface to a class may seem appealing, it's important to note that in TypeScript's structural type system, where types are primarily based on shapes, you can create objects with the same structure as a given class, as demonstrated in the code snippet below:
class C {
a: number = 10;
b: boolean = true;
c: string = "hello";
}
let x = new C()
let y: C = {
a: 10, b: true, c: "hello",
}
// Works!
x = y; // No issues
y = x; // No issues
In this scenario, x
and y
have the same type. However, applying instanceof
on either object will yield opposite results, highlighting how the use of structural types in TypeScript can affect type checking via instanceof
.