value instanceof SomeClass é uma verificação do JavaScript que roda em tempo de execução: é true quando SomeClass.prototype está na cadeia de protótipos do objeto, o que significa que o objeto foi criado com new SomeClass (ou com uma subclasse). O TypeScript estreita value para SomeClass dentro da verificação.
Use instanceof para objetos criados a partir de classes, e typeof para primitivos. Aqui os dois são necessários: o instanceof separa o Date, e depois o typeof divide o que sobra.
Narrowing das suas próprias classes
O instanceof estreita para a classe no ramo true e a remove no ramo false, então uma union de classes pode ser tratada um membro por vez.
Uma instância de subclasse também passa na verificação da classe pai: se Square extends Rect, então new Square(2) instanceof Rect é true. Teste primeiro a classe mais específica quando os ramos são diferentes.
Subclasses de Error no catch
O uso mais comum do instanceof é no catch. Com strict, o valor capturado é unknown (qualquer coisa pode ser lançada), e o instanceof é como você volta a ter um erro tipado.
Saída:
404: /missing.txt
TypeError: path must be absolute
class X extends Error funciona com instanceof em todo target que o TypeScript 7 suporta (ES2015 e posteriores). O conselho antigo de chamar Object.setPrototypeOf(this, X.prototype) no construtor valia para código compilado para ES5, um target que o TypeScript 7 removeu.
instanceof não funciona com interfaces nem types
Interfaces e type aliases existem só para o compilador. Depois da compilação não há nenhum valor User para comparar, então o TypeScript recusa a verificação:
O compilador mostra index.ts(8,24): error TS2693: 'User' only refers to a type, but is being used as a value here. Há duas soluções. Verifique você mesmo o formato com um type guard, uma função que retorna value is User:
Ou, se é o seu código que cria esses objetos, transforme User em uma classe e crie-os com new; aí o instanceof funciona. A página sobre type guards trata de predicates e assertion functions em detalhe.
O tipo certo não é a instância certa
O TypeScript compara tipos pela estrutura: um objeto literal com os mesmos membros de uma classe pode ser atribuído ao tipo da classe. O instanceof não olha a estrutura. Ele percorre a cadeia de protótipos, e um objeto que nunca foi criado com new falha na verificação mesmo quando o compilador o aceita como aquele tipo.
A última linha importa. structuredClone, JSON.parse(JSON.stringify(...)) e mensagens entre workers retornam objetos simples sem o protótipo da classe, mesmo que o tipo estático deles ainda diga Point. Quando instâncias de classes atravessam uma fronteira dessas, reconstrua-as (new Point(copy.x, copy.y)) antes de depender do instanceof ou dos métodos.
instanceof e primitivos
Primitivos (string, number, boolean...) não são objetos e não têm cadeia de protótipos, então "hi" instanceof String é false. O TypeScript aponta o erro quando consegue: com um valor tipado como string do lado esquerdo, o instanceof gera o erro TS2358, The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. Use typeof para primitivos.
| Valor | Verificação instanceof | Resultado |
|---|---|---|
new Date() | instanceof Date | true |
[1, 2] | instanceof Array | true (mas prefira Array.isArray) |
new TypeError("x") | instanceof Error | true (subclasse) |
{ x: 1, y: 2 } | instanceof Point | false (nunca foi construído) |
Object.create(null) | instanceof Object | false (sem protótipo) |
"hi" | instanceof String | false (primitivo) |
Valores de outro realm
O instanceof compara com um objeto construtor específico. Código rodando em outro realm (um iframe, ou um contexto vm do Node) tem o próprio Array, Error e Date, então um array criado lá falha em instanceof Array aqui. O mesmo acontece quando duas cópias de um mesmo pacote npm acabam no node_modules: cada cópia tem a própria classe, e uma instância de uma falha no instanceof contra a outra. Para arrays, Array.isArray funciona entre realms. Para os seus próprios tipos, verificar uma propriedade (um type guard, ou um campo kind) evita o problema por completo.
Perguntas frequentes
Como verificar se um objeto é instância de uma classe no TypeScript?
Use value instanceof ClassName. É uma verificação em tempo de execução (JavaScript puro), e o TypeScript estreita value para ClassName dentro do if. Funciona com classes nativas como Date, Map e Error e também com as suas.
Posso usar instanceof com uma interface no TypeScript?
Não. Interfaces e type aliases são apagados quando o TypeScript compila para JavaScript, então não há nada contra o que comparar em tempo de execução. x instanceof User com uma interface User gera o erro TS2693, "'User' only refers to a type, but is being used as a value here." Verifique as propriedades com uma função type guard, ou transforme User em uma classe se você mesmo cria os objetos.
Por que instanceof retorna false para um objeto do tipo certo?
Os tipos do TypeScript são estruturais: um objeto literal { x: 1, y: 2 } pode ser atribuído a um tipo de classe Point se tiver os mesmos membros. Mas o instanceof verifica a cadeia de protótipos, e o literal nunca foi criado com new Point, então o resultado é false. O mesmo acontece com instâncias de classes que passaram por JSON, structuredClone ou um canal de mensagens, que voltam como objetos simples.
O instanceof funciona com classes de Error personalizadas no TypeScript?
Sim, com qualquer target moderno. class NotFound extends Error {} e depois err instanceof NotFound é true. O antigo problema em que ele retornava false só afetava a saída compilada para ES5, e o TypeScript 7 não suporta mais o target ES5.
Por que "hello" instanceof String é false?
Uma string literal é um primitivo, não um objeto, então não tem cadeia de protótipos para verificar. instanceof String só é verdadeiro para objetos wrapper criados com new String(). O TypeScript rejeita instanceof em um valor tipado como string (TS2358); use typeof value === "string" para primitivos.