Introdução: o eterno debate dos desenvolvedores TypeScript
Se você já escreveu em TypeScript, certamente já se deparou com a pergunta: "Quando usar interface e quando usar type?" Essa questão acumulou milhares de visualizações no Stack Overflow e se tornou uma verdadeira pedra no sapato para iniciantes. Vamos entender de uma vez por todas esse dilema.
TypeScript é uma extensão do JavaScript que adiciona tipagem estática. E temos duas ferramentas principais para descrever a estrutura de dados: Interface e Type Alias. À primeira vista, elas fazem a mesma coisa, mas o diabo está nos detalhes. Neste artigo, não vamos apenas listar as diferenças — vamos mostrá-las com exemplos reais e dar recomendações claras.
O que é Interface?
Interface é uma forma de descrever a estrutura de um objeto. É como um molde para os dados: você diz ao TypeScript quais propriedades e métodos o objeto deve ter.
// Interface básicainterface User { name: string; age: number; email?: string; // propriedade opcional readonly id: number; // apenas leitura}
// Usoconst user: User = { name: "Ana", age: 25, id: 1};Interfaces podem herdar umas das outras, tornando-as ideais para descrever hierarquias:
interface Animal { name: string; sound(): void;}
interface Dog extends Animal { breed: string; wagTail(): void;}
// Agora Dog contém todos os campos de Animal + os seusconst myDog: Dog = { name: "Rex", breed: "Pastor Alemão", sound() { console.log("Au au!"); }, wagTail() { console.log("Abanando o rabo"); }};O que é Type Alias?
Type Alias (apelido de tipo) é uma ferramenta mais flexível. Ela pode descrever não apenas objetos, mas também primitivos, uniões e interseções de tipos.
// Tipo para primitivotype ID = string | number;
// Tipo para objetotype UserType = { name: string; age: number;};
// Tipo para funçãotype Greeting = (name: string) => string;
// Union Type (união)type Status = "active" | "inactive" | "pending";
// Intersection Type (interseção)type Person = { name: string };type Employee = Person & { salary: number };O superpoder principal dos tipos são os union types. Interfaces não conseguem fazer isso:
// ❌ Não é possível com interface// interface Status = "active" | "inactive"; // Erro!
// ✅ Com type é fácil!type Status = "active" | "inactive" | "pending";
function processStatus(status: Status) { switch (status) { case "active": console.log("Ativo"); break; case "inactive": console.log("Inativo"); break; case "pending": console.log("Pendente"); break; }}Diferenças principais: Interface vs Type
Vamos detalhar como elas diferem na prática.
1. União e interseção de tipos
Type suporta union (|) e intersection (&) diretamente. Interface — apenas através de extends.
// Union — apenas com typetype Success = { data: string };type Error = { error: string };type Result = Success | Error; // Permitido!
// Intersectiontype Full = Success & Error; // Permitido!
// Para interface, seria necessário criar interfaces separadasinterface IResult extends Success, Error {} // Funciona, mas é verboso2. Declaration merging (fusão de declarações)
Este é um recurso único das interfaces. Se você declarar duas interfaces com o mesmo nome, o TypeScript as mescla.
// Primeira interfaceinterface User { name: string;}
// Segunda interface com o mesmo nomeinterface User { age: number;}
// Resultado: User = { name: string; age: number; }const user: User = {