“`html
Diferenças entre type e interfaces no TypeScript
No dia a dia parece que type e interface fazem “quase a mesma coisa”.
Mas existem diferenças importantes que afetam extensibilidade, composição e legibilidade do seu código.
extendsComposição: type via interseção (
&)Declaração merges: interface
Tipos avançados: type ganha
1) O que ambos fazem (e por que você usa os dois)
Tanto type quanto interface descrevem a forma de um valor no TypeScript.
Na prática, você está definindo um contrato: quais propriedades existem, que tipos elas possuem e quais restrições devem ser respeitadas.
Quando o seu objetivo é descrever objetos com propriedades, as duas abordagens costumam funcionar.
A diferença aparece quando você tenta ir além: criar uniões, fazer composição complexa, ou estender/mesclar definições em módulos e bibliotecas.
2) Extensão e composição: extends vs interseção (&)
Interfaces foram desenhadas com uma ênfase natural em herança de contratos.
Você estende uma interface com extends.
- interface: “estende” outra definição
- type: compõe tipos usando interseção (
&) e pode usar uniões (|)
Em termos práticos: se você quer uma hierarquia clara de contratos (especialmente para APIs públicas),
a interface costuma ficar mais direta.
Se você quer “montar” tipos a partir de peças (ex.: interseções e mapeamentos), type tende a ser mais expressivo.
3) Merging (declarações que se juntam): o diferencial clássico das interfaces
Uma das diferenças mais conhecidas é que interfaces suportam declaration merging.
Ou seja: você pode declarar a mesma interface em lugares diferentes e o TypeScript “une” as propriedades.
Isso é especialmente útil quando você quer:
- estender tipos de forma incremental;
- aprimorar definições de bibliotecas (em padrões de augmentação);
- organizar contratos por módulo sem criar um tipo “grande” no mesmo arquivo.
Já type não faz merging. Se você declarar o mesmo alias duas vezes, é erro.
Essa característica influencia como você estrutura seu projeto.
4) Tipos avançados: type tem mais liberdade
type é um “alias” para qualquer expressão de tipo.
Na prática, isso significa que ele se encaixa naturalmente com construções avançadas:
uniões, interseções, tipos condicionais, mapeamentos e inferência.
Interfaces também podem representar objetos, mas têm menos liberdade para expressar lógica de tipos.
Se você precisa modelar estados ou formas condicionais, type tende a ser a escolha mais natural.
Use interface quando seu objetivo for contratos extensíveis e “negociáveis” ao longo do projeto.
Use type quando precisar de composição avançada (uniões/interseções) ou modelagem mais expressiva.
Exemplo completo: escolha entre interface e type na prática
Abaixo eu mostro:
(1) interface com extensão,
(2) type com interseção/unidão para modelar estados,
(3) uma ideia de “merging” conceitual para interfaces.
.ts
type ID = string | number;
interface BaseUser {
id: ID;
email: string;
}
interface AdminUser extends BaseUser {
role: "admin";
permissions: string[];
}
// Estado do request usando type (união + tipos específicos)
type RequestState =
| { status: "idle" }
| { status: "loading"; startedAt: number }
| { status: "success"; data: unknown }
| { status: "error"; message: string };
// Composição de tipos com interseção (&)
type Paginated<T> = {
page: number;
pageSize: number;
items: T[];
};
type UserListResult = Paginated<AdminUser> & {
total: number;
};
// Uso
const admin: AdminUser = {
id: 1,
email: "dev@yurideveloper.com",
role: "admin",
permissions: ["users:read", "users:write"],
};
const state: RequestState = { status: "loading", startedAt: Date.now() };
const result: UserListResult = {
page: 1,
pageSize: 10,
items: [admin],
total: 23,
};
// Observação sobre merging:
// Se você declarar "interface BaseUser" em outro arquivo com propriedades adicionais,
// o TypeScript pode mesclar as definições (dependendo do cenário e do nome).]
Nota: o merging real costuma aparecer em augmentação por módulo ou em cenários específicos de organização.
O ponto aqui é entender a propriedade “declaration merging” como capacidade das interfaces, não como algo que você usa do mesmo jeito que type.
Resumo objetivo: como decidir em projetos reais
Se eu tiver que decidir rapidamente, eu penso assim:
-
Prefira interface quando o contrato faz parte de uma API e tende a ser estendido e negociado com clareza.
Além disso, interfaces ajudam muito quando você quer aproveitar declaration merging. -
Prefira type quando você precisa de uniões/interseções para modelar estados, fluxos e estruturas condicionais.
Ele também é a opção mais natural para tipos avançados. -
Consistência vence: em um projeto, padronize e evite misturar critérios sem motivo.
O custo de leitura aumenta quando cada arquivo decide sozinho.
“`
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!