value instanceof SomeClass es una comprobación de JavaScript que se ejecuta en tiempo de ejecución: es true cuando SomeClass.prototype está en la cadena de prototipos del objeto, lo que significa que el objeto se creó con new SomeClass (o con una subclase). TypeScript estrecha value a SomeClass dentro de la comprobación.
Usa instanceof para objetos creados a partir de clases, y typeof para primitivos. Aquí hacen falta los dos: instanceof separa el Date y luego typeof divide lo que queda.
Estrechar tus propias clases
instanceof estrecha a la clase en la rama true y la quita en la rama false, así que una unión de clases se puede manejar miembro a miembro.
Una instancia de una subclase también pasa la comprobación de su clase padre: si Square extends Rect, entonces new Square(2) instanceof Rect es true. Comprueba primero la clase más específica cuando las ramas son distintas.
Subclases de Error en catch
El uso más habitual de instanceof está en catch. Con strict, el valor capturado es unknown (se puede lanzar cualquier cosa), e instanceof es la forma de volver a un error tipado.
Salida:
404: /missing.txt
TypeError: path must be absolute
class X extends Error funciona con instanceof en todos los targets que admite TypeScript 7 (ES2015 y posteriores). El antiguo consejo de llamar a Object.setPrototypeOf(this, X.prototype) en el constructor se aplicaba al código compilado a ES5, un target que TypeScript 7 ha eliminado.
instanceof no funciona con interfaces ni con tipos
Las interfaces y los alias de tipo solo existen para el compilador. Después de compilar no hay ningún valor User con el que comparar, así que TypeScript rechaza la comprobación:
El compilador informa index.ts(8,24): error TS2693: 'User' only refers to a type, but is being used as a value here. Hay dos soluciones. Comprueba tú la forma con un type guard, una función que devuelve value is User:
O, si es tu código el que crea estos objetos, convierte User en una clase y constrúyelos con new; así instanceof funciona. La página de type guards explica en detalle los predicados y las funciones de aserción.
El tipo correcto no es la instancia correcta
TypeScript compara los tipos por estructura: un objeto literal con los mismos miembros que una clase se puede asignar al tipo de esa clase. instanceof no mira la estructura. Recorre la cadena de prototipos, y un objeto que nunca se creó con new no la pasa aunque el compilador lo acepte como de ese tipo.
La última línea es importante. structuredClone, JSON.parse(JSON.stringify(...)) y los mensajes entre workers devuelven objetos normales sin el prototipo de la clase, aunque su tipo estático pueda seguir diciendo Point. Cuando instancias de clases cruzan una frontera así, reconstrúyelas (new Point(copy.x, copy.y)) antes de confiar en instanceof o en sus métodos.
instanceof y los primitivos
Los primitivos (string, number, boolean...) no son objetos y no tienen cadena de prototipos, así que "hi" instanceof String es false. TypeScript señala el error cuando puede: con un valor de tipo string a la izquierda, instanceof es el error TS2358, The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. Usa typeof para los primitivos.
| Valor | Comprobación instanceof | Resultado |
|---|---|---|
new Date() | instanceof Date | true |
[1, 2] | instanceof Array | true (pero mejor Array.isArray) |
new TypeError("x") | instanceof Error | true (subclase) |
{ x: 1, y: 2 } | instanceof Point | false (nunca se construyó) |
Object.create(null) | instanceof Object | false (sin prototipo) |
"hi" | instanceof String | false (primitivo) |
Valores de otro realm
instanceof compara con un objeto constructor concreto. El código que se ejecuta en otro realm (un iframe, o un contexto vm de Node) tiene sus propios Array, Error y Date, así que un array creado allí no pasa instanceof Array aquí. Lo mismo pasa cuando acaban dos copias de un mismo paquete npm en node_modules: cada copia tiene su propia clase, y una instancia de una no pasa instanceof contra la otra. Para arrays, Array.isArray funciona entre realms. Para tus propios tipos, comprobar una propiedad (un type guard o un campo kind) evita el problema por completo.
Preguntas frecuentes
¿Cómo compruebo si un objeto es una instancia de una clase en TypeScript?
Usa value instanceof ClassName. Es una comprobación en tiempo de ejecución (JavaScript normal), y TypeScript estrecha value a ClassName dentro del if. Funciona con clases integradas como Date, Map y Error y también con las tuyas.
¿Puedo usar instanceof con una interfaz en TypeScript?
No. Las interfaces y los alias de tipo se borran cuando TypeScript compila a JavaScript, así que en tiempo de ejecución no hay nada con lo que comparar. x instanceof User con una interfaz User es el error TS2693, "'User' only refers to a type, but is being used as a value here." Comprueba las propiedades con una función type guard, o convierte User en una clase si creas tú los objetos.
¿Por qué instanceof devuelve false para un objeto del tipo correcto?
Los tipos de TypeScript son estructurales: un objeto literal { x: 1, y: 2 } se puede asignar al tipo de una clase Point si tiene los mismos miembros. Pero instanceof comprueba la cadena de prototipos, y el literal nunca se creó con new Point, así que da false. Lo mismo pasa con instancias de clases que han pasado por JSON, structuredClone o un canal de mensajes, que vuelven como objetos normales.
¿instanceof funciona con clases Error personalizadas en TypeScript?
Sí, con cualquier target moderno. class NotFound extends Error {} y después err instanceof NotFound da true. El antiguo problema de que devolviera false solo afectaba a la salida compilada a ES5, y TypeScript 7 ya no admite el target ES5.
¿Por qué "hello" instanceof String es false?
Un literal de string es un primitivo, no un objeto, así que no tiene cadena de prototipos que comprobar. instanceof String solo es true para objetos envoltorio creados con new String(). TypeScript rechaza instanceof sobre un valor de tipo string (TS2358); usa typeof value === "string" para los primitivos.