Verificação de tipos de interfaces em TypeScript: perguntas frequentes e respostas

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

Introdução: por que as interfaces não funcionam durante a execução?

\n\n

Olá, amigo! Se você já escreveu em TypeScript, certamente já se deparou com esta situação: você cria uma interface perfeita, descreve todos os campos, verifica os tipos na fase de compilação — e de repente percebe que em tempo de execução (runtime) seu código se comporta como se nenhuma interface existisse. Familiar? 🎯

\n\n

Esta é uma das perguntas mais populares no Stack Overflow: "Interface type check with TypeScript" — milhares de visualizações, centenas de respostas. E não é surpresa, pois o TypeScript apaga as interfaces durante a compilação. Ao contrário das classes, as interfaces são uma construção puramente declarativa para o desenvolvedor e o compilador. Em JavaScript, elas não existem.

\n\n

Neste artigo, vamos entender como contornar essa limitação, aprender a verificar se um objeto corresponde a uma interface em tempo de execução e responder às perguntas mais frequentes. Vamos lá! 🚀

\n\n

Por que queremos verificar interfaces?

\n\n

Imagine: você recebe dados de uma API, de um formulário ou de um WebSocket. Você tem certeza de que eles correspondem à interface User, mas de repente chega um objeto sem o campo email ou com o tipo errado. Se não verificar — seu código vai falhar com um erro. As interfaces do TypeScript verificam apenas durante o desenvolvimento, não em produção. Portanto, são necessárias verificações em runtime.

\n\n

O problema: interfaces não existem em tempo de execução

\n\n

Em TypeScript, as interfaces são "açúcar sintático" para tipagem estática. Quando você compila o código, as interfaces desaparecem. Aqui está um exemplo simples:

\n\n
interface User {\n  name: string;\n  age: number;\n}\n\nconst data: unknown = JSON.parse('{"name": "Alice"}');\nif (data instanceof User) { // ❌ Erro! User é uma interface, não uma classe\n  console.log(data.name);\n}
\n\n

O compilador dirá: 'User' only refers to a type, but is being used as a value here. Esta é a principal armadilha para iniciantes. Mas não se preocupe — existem várias maneiras comprovadas de contornar isso.

\n\n

Método 1: Guardiões de tipo personalizados (User-Defined Type Guards)

\n\n

A maneira mais popular e elegante é escrever uma função guardiã de tipo. Ela verifica a estrutura do objeto e retorna true/false, e o TypeScript "entende" que dentro do bloco com true o objeto corresponde exatamente à interface.

\n\n
interface User {\n  name: string;\n  age: number;\n  email?: string; // campo opcional\n}\n\nfunction isUser(obj: unknown): obj is User {\n  if (typeof obj !== 'object' || obj === null) return false;\n\n  const user = obj as Record<string, unknown>;\n  return (\n    typeof user.name === 'string' &&\n    typeof user.age === 'number' &&\n    (user.email === undefined || typeof user.email === 'string')\n  );\n}\n\n// Exemplo de uso\nconst data: unknown = JSON.parse('{"name": "Bob", "age": 30}');\n\nif (isUser(data)) {\n  // Agora o TypeScript sabe que data é User\n  console.log(data.name.toUpperCase()); // ✅ Funciona\n}
\n\n

Vantagens: controle total, tipos são inferidos corretamente, fácil de estender.
\nDesvantagens: precisa escrever manualmente para cada interface (mas existem bibliotecas!)

\n\n

O que é obj is User?

\n\n

Esta é a sintaxe do guardião de tipo. Ela diz ao TypeScript: "Se a função retornar true, então o argumento obj pode ser considerado do tipo User". Esta é a mágica que torna a verificação em runtime útil para análise estática.

\n\n

Método 2: Usar classes em vez de interfaces

\n\n

As classes são a única construção do TypeScript que é preservada em JavaScript. Se você precisa verificar o tipo em tempo de execução, pode substituir a interface por uma classe com verificação através de instanceof.

\n\n
class User {\n  constructor(\n    public name: string,\n    public age: number,\n    public email?: string\n  ) {}\n}\n\nconst data = new User('Charlie', 25);\nif (data instanceof User) {\n  consol                

Blogs

Book Recommendations