in Estreitamento com o operador in

Última atualização: 2026-10-22

in Estreitamento com o operador in

O operador in verifica se um nome de propriedade existe em um objeto, e o TypeScript usa isso para estreitar a união ao membro que possui essa propriedade. Quando os membros da união não têm um campo discriminador comum e são interfaces (caso em que instanceof não está disponível), in é a forma mais prática de diferenciar estruturas.

GrupoRestrição e Asserções de Tipos
TipoOperador
Modo strictNão necessário

ℹ️ Info O editor transpila TypeScript para JavaScript e o executa (sem verificação de tipos); veja a Saída de cada exemplo para o resultado da verificação.

📝 Sintaxe

interface Bird { fly: () => void }
interface Fish { swim: () => void }

function move(animal: Bird | Fish) {
  if ("swim" in animal) {
    animal.swim();   // estreitado para Fish
  } else {
    animal.fly();    // estreitado para Bird
  }
}

⚙️ Parâmetros

"key" in objEm tempo de execução, verifica se key é uma propriedade de obj (incluindo a cadeia de protótipos) e retorna um boolean; o TS também estreita obj para o membro da união que contém essa propriedade

Retorno:A expressão in retorna um boolean; o estreitamento ocorre em tempo de compilação e depende da exclusividade de propriedades entre os membros da união (ter ou não ter determinada propriedade).

▶ Exemplo

Edite o código abaixo e clique em Testar para ver o resultado transpilado:

Saída:

bubble...
it swims
flap!
it flies

(Saída de execução após a transpilação; animal.swim() passa na verificação de tipos porque o estreitamento por in já fixou animal como Fish — o estreitamento é garantido estaticamente pelo tsc, em tempo de execução existem apenas os valores)

💡 Observações

ℹ️ Info in testa a existência de propriedades, incluindo as herdadas na cadeia de protótipos. Objetos simples possuem membros nativos como toString e constructor, portanto faça a verificação com nomes de campos do seu próprio domínio.
⚠️ Atenção O estreitamento por in depende da exclusividade: se dois membros têm o mesmo campo (diferindo apenas no tipo), in ajuda pouco. Nesse cenário, prefira uma união discriminada com valores literais distintos.
💡 Dica in também é a sintaxe central dos tipos mapeados ([K in keyof T]), mas esse é o uso no nível de tipo; esta entrada cobre o operador de tempo de execução mais o estreitamento em tempo de compilação.
Mais casos em breve.

📚 Tutoriais relacionados

❓ Perguntas frequentes

P Como escolher entre estreitamento com in e uniões discriminadas?
R Se for possível dar a cada membro um campo literal distinto (type/status/kind), use uma união discriminada — mais clara e compatível com verificações de exaustividade. Para uniões de terceiros sem discriminador, diferencie estruturalmente com in.
P Propriedades opcionais podem enganar o estreitamento com in?
R Sim. Uma propriedade opcional flag?: boolean pode de fato estar ausente, então flag in obj === false não prova pertencimento ao outro ramo. Confirme que a propriedade é obrigatória em um membro e ausente nos demais antes de confiar no in.
P O in ainda estreita corretamente depois que delete remove uma propriedade?
R Sim — após delete obj.key, o resultado do in em tempo de execução é false e o TS estreita para o membro sem essa propriedade. Mas o TS estrito já torna a exclusão de uma propriedade obrigatória um erro de compilação, justamente para manter os tipos de execução e os declarados em sincronia.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%