Como excluir uma propriedade de um tipo em TypeScript: salvando o código de bagagem desnecessária
\n\nVocê já se deparou com uma situação em que tem uma grande interface ou tipo, e precisa criar um novo tipo que é quase igual, mas sem um ou dois campos? Duplicar todo o código? Copiar 15 linhas e excluir uma? Existe uma maneira mais elegante. Hoje vamos ver como excluir uma propriedade de um tipo em TypeScript — este é um dos utilitários mais populares que evita duplicação e torna o código mais limpo.
\n\nEste tópico é um verdadeiro sucesso no Stack Overflow. A pergunta "Exclude property from type" recebe milhares de visualizações porque, mais cedo ou mais tarde, todo desenvolvedor precisa remover um campo de um tipo ou excluir uma propriedade de uma interface. Vamos entender passo a passo, começando com exemplos simples e terminando com técnicas avançadas.
\n\nProblema: por que excluir campos de um tipo?
\n\nImagine que você tem uma interface User:
interface User {\n id: number;\n name: string;\n email: string;\n password: string;\n createdAt: Date;\n}\n\nVocê quer criar um formulário de registro, onde o usuário insere nome, email e senha. Mas o id é gerado no servidor e o createdAt é automático. Você precisa de um tipo NewUser que contenha apenas name, email e password. Como fazer isso?
Uma solução ruim é declarar uma nova interface do zero:
\n\ninterface NewUser {\n name: string;\n email: string;\n password: string;\n}\n\nIsso funciona, mas viola o princípio DRY (Don't Repeat Yourself). Se alterarmos o tipo de name em User, teremos que alterar também em NewUser. É aqui que entra a exclusão de propriedades de um tipo.
O tipo utilitário Omit: a ferramenta principal
\n\nTypeScript fornece o tipo utilitário embutido Omit<Type, Keys>. Ele cria um novo tipo, excluindo as chaves especificadas do tipo original. A sintaxe é simples:
type NewUser = Omit<User, 'id' | 'createdAt'>;\n\nAgora, NewUser contém apenas name, email e password. Se alterarmos email para Email em User, o NewUser será atualizado automaticamente.
Vamos verificar na prática:
\n\nconst newUser: NewUser = {\n name: 'Ana',\n email: 'ana@exemplo.com',\n password: 'seguro123'\n}; // ✅ Tudo ok\n\nconst invalidUser: NewUser = {\n name: 'Ana',\n email: 'ana@exemplo.com',\n password: 'seguro123',\n id: 1 // ❌ Erro: id não existe no tipo NewUser\n};\n\nObservação: Omit funciona tanto com interfaces quanto com tipos. É uma ferramenta universal para excluir campos de um tipo.
Como o Omit funciona internamente?
\n\nPara entender melhor como o TypeScript exclui propriedades de um tipo, vamos ver os bastidores. Omit é uma combinação de dois outros utilitários: Pick e Exclude.
Veja como ele é definido na biblioteca padrão do TypeScript:
\n\ntype Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;\n\nVamos analisar passo a passo:
\n- \n
keyof T— obtém todas as chaves do tipo T (por exemplo,'id' | 'name' | 'email' | 'password' | 'createdAt') \n Exclude<keyof T, K>— exclui dessas chaves aquelas especificadas em K (obtemos'name' | 'email' | 'password') \n Pick<T, ...>— seleciona de T apenas as chaves restantes \n
Assim, a exclusão de uma propriedade de uma interface se resume a uma filtragem de chaves. Elegante, não é?
\n\nPick: o lado oposto do Omit
\n\nÀs vezes, é mais fácil não excluir, mas sim selecionar