value instanceof SomeClass is a JavaScript check that runs at run time: it is true when SomeClass.prototype is in the object's prototype chain, which means the object was created with new SomeClass (or a subclass). TypeScript narrows value to SomeClass inside the check.
Use instanceof for objects made from classes, and typeof for primitives. Here both are needed: instanceof separates the Date, then typeof splits what is left.
Narrowing Your Own Classes
instanceof narrows to the class in the true branch and removes it in the false branch, so a union of classes can be handled one member at a time.
A subclass instance also passes the check for its parent: if Square extends Rect, then new Square(2) instanceof Rect is true. Test the most specific class first when the branches differ.
Error Subclasses in catch
The most common use of instanceof is in catch. Under strict, the caught value is unknown (anything can be thrown), and instanceof is how you get back to a typed error.
Output:
404: /missing.txt
TypeError: path must be absolute
class X extends Error works with instanceof on every target TypeScript 7 supports (ES2015 and later). Older advice to call Object.setPrototypeOf(this, X.prototype) in the constructor applied to code compiled to ES5, a target TypeScript 7 has removed.
instanceof Does Not Work With Interfaces or Types
Interfaces and type aliases exist only for the compiler. After compilation there is no User value to compare against, so TypeScript refuses the check:
The compiler reports index.ts(8,24): error TS2693: 'User' only refers to a type, but is being used as a value here. There are two fixes. Check the shape yourself with a type guard, a function that returns value is User:
Or, if your code creates these objects, make User a class and construct them with new; then instanceof works. The type guards page covers predicates and assertion functions in detail.
The Right Type Is Not the Right Instance
TypeScript compares types by structure: an object literal with the same members as a class is assignable to the class type. instanceof does not look at structure. It walks the prototype chain, and an object that was never created with new fails it even when the compiler accepts it as that type.
The last line matters. structuredClone, JSON.parse(JSON.stringify(...)) and messages between workers all return plain objects without the class prototype, even though their static type can still say Point. When class instances cross such a boundary, rebuild them (new Point(copy.x, copy.y)) before relying on instanceof or on methods.
instanceof and Primitives
Primitives (string, number, boolean...) are not objects and have no prototype chain, so "hi" instanceof String is false. TypeScript flags the mistake when it can: with a value typed string on the left, instanceof is error TS2358, The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. Use typeof for primitives.
| Value | instanceof check | Result |
|---|---|---|
new Date() | instanceof Date | true |
[1, 2] | instanceof Array | true (but prefer Array.isArray) |
new TypeError("x") | instanceof Error | true (subclass) |
{ x: 1, y: 2 } | instanceof Point | false (never constructed) |
Object.create(null) | instanceof Object | false (no prototype) |
"hi" | instanceof String | false (primitive) |
Cross-Realm Values
instanceof compares against one specific constructor object. Code running in another realm (an iframe, or a Node vm context) has its own Array, Error and Date, so an array created there fails instanceof Array here. The same happens when two copies of one npm package end up in node_modules: each copy has its own class, and an instance from one fails instanceof against the other. For arrays, Array.isArray works across realms. For your own types, checking a property (a type guard, or a kind field) avoids the problem entirely.
Frequently Asked Questions
How do I check if an object is an instance of a class in TypeScript?
Use value instanceof ClassName. It is a runtime check (plain JavaScript), and TypeScript narrows value to ClassName inside the if. It works for built-in classes such as Date, Map and Error as well as your own.
Can I use instanceof with an interface in TypeScript?
No. Interfaces and type aliases are erased when TypeScript compiles to JavaScript, so there is nothing to check against at run time. x instanceof User with an interface User is error TS2693, "'User' only refers to a type, but is being used as a value here." Check the properties with a type guard function instead, or make User a class if you create the objects yourself.
Why does instanceof return false for an object of the right type?
TypeScript types are structural: an object literal { x: 1, y: 2 } is assignable to a Point class type if it has the same members. But instanceof checks the prototype chain, and the literal was never created with new Point, so it is false. The same happens to class instances that went through JSON, structuredClone or a message channel, which come back as plain objects.
Does instanceof work with custom Error classes in TypeScript?
Yes, with any modern target. class NotFound extends Error {} then err instanceof NotFound is true. The old problem where it returned false only affected output compiled to ES5, and TypeScript 7 no longer supports the ES5 target.
Why is "hello" instanceof String false?
A string literal is a primitive, not an object, so it has no prototype chain to check. instanceof String is only true for wrapper objects made with new String(). TypeScript rejects instanceof on a value typed string (TS2358); use typeof value === "string" for primitives.