Tipificação de classes em TypeScript: como verificar o tipo de um objeto

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Como verificar o tipo de classe em TypeScript: do iniciante ao profissional

\n\n

Você já escreveu em TypeScript, recebeu um objeto de tipo desconhecido e pensou: "E quem é você, afinal?"? Essa pergunta atormenta milhares de desenvolvedores — não é à toa que o tópico class type check in TypeScript acumulou centenas de milhares de visualizações no Stack Overflow. E hoje vamos entender de uma vez por todas como verificar corretamente os tipos de classes em TypeScript.

\n\n

Neste artigo, você aprenderá:

\n
    \n
  • Por que typeof não funciona para classes
  • \n
  • Como usar instanceof como um canivete suíço
  • \n
  • O que são type guards e como eles salvam seu código
  • \n
  • Como criar sua própria verificação de tipo com is
  • \n
  • Exemplos reais da prática
  • \n
\n\n

Vamos nessa!

\n\n

O problema: por que typeof é impotente aqui?

\n\n

Em JavaScript, existe o operador typeof, que funciona perfeitamente com primitivos:

\n\n
typeof "hello" // "string"\ntypeof 42      // "number"\ntypeof true    // "boolean"
\n\n

Mas quando se trata de classes, typeof falha:

\n\n
class Dog {}\nclass Cat {}\n\nconst pet = new Dog();\n\ntypeof pet; // "object" — inútil!\ntypeof Dog; // "function" — também não serve
\n\n

Por quê? Porque as classes em JavaScript são apenas açúcar sintático sobre funções construtoras. O typeof vê apenas "objeto" ou "função", mas não distingue qual classe é.

\n\n

É aqui que entra o class type check in TypeScript — um arsenal completo de ferramentas que ajudará você a determinar exatamente com qual instância de classe está lidando.

\n\n

Método 1: instanceof — seu principal aliado

\n\n

A maneira mais direta e clara de verificar o tipo de uma classe é o operador instanceof. Ele verifica se a classe está na cadeia de protótipos do objeto:

\n\n
class Animal {\n  name: string;\n  constructor(name: string) {\n    this.name = name;\n  }\n}\n\nclass Dog extends Animal {\n  bark() {\n    console.log("Woof!");\n  }\n}\n\nclass Cat extends Animal {\n  meow() {\n    console.log("Meow!");\n  }\n}\n\nfunction handleAnimal(animal: Animal) {\n  if (animal instanceof Dog) {\n    // TypeScript sabe que animal é um Dog\n    animal.bark();\n  } else if (animal instanceof Cat) {\n    animal.meow();\n  } else {\n    console.log(`Animal desconhecido: ${animal.name}`);\n  }\n}\n\nconst rex = new Dog("Rex");\nhandleAnimal(rex); // "Woof!"
\n\n

Observe: após a verificação animal instanceof Dog, o TypeScript automaticamente reduz o tipo (type narrowing) e permite chamar métodos de Dog sem erros. Essa é a magia dos type guards — protetores de tipo embutidos.

\n\n

Quando o instanceof não funciona?

\n
    \n
  • Ao trabalhar com diferentes janelas/frames (objetos globais diferentes)
  • \n
  • Se as classes forem definidas em módulos diferentes com versões diferentes
  • \n
  • Ao verificar interfaces (elas não existem em tempo de execução)
  • \n
\n\n

Método 2: Type guards personalizados com o operador is

\n\n

Às vezes, o instanceof não é suficiente. Por exemplo, você pode querer verificar não apenas a classe, mas também condições adicionais. É aqui que entram os type guards personalizados com a palavra-chave is:

\n\n
interface Bird {\n  fly(): void;\n  layEggs(): void;\n}\n\ninterface Fish {\n  swim(): void;\n  layEggs(): void;\n}\n\nfunction isFish(pet: Bird | Fish): pet is Fish {\n  return (pet as Fish).swim !== undefined;\n}\n\nfunction move(pet: Bird | Fish) {\n  if (isFish(pet)) {\n    // TypeScript sabe: pet é um Fish\n    pet.swim();\n  } else {\n    pet.fly();\n  }\n}
\n\n

Observe a sintaxe: pet is Fish no tipo de retorno. Isso diz ao TypeScript: "Se esta função retornar true, então o parâmetro pet é um Fish". Agora o TypeScript reduzirá o tipo em todos os lugares onde você usar

Blogs

Book Recommendations