Skip to main content

Merge de tipos | Typescript

  • Merge de tipos | Typescript

Mergear tipos no TypeScript é uma prática comum para combinar estruturas, reaproveitar modelos e criar tipos mais específicos a partir de outros já existentes. O TypeScript oferece diferentes maneiras de fazer isso, cada uma adequada a um cenário.


Intersection Types (&)

A forma mais direta de mergear dois tipos é usando o operador de interseção (&). Ele cria um novo tipo que contém todas as propriedades dos tipos combinados.

type A = {
nome: string;
};

type B = {
idade: number;
};

type AB = A & B;

Resultado:

{
nome: string;
idade: number;
}

Essa abordagem é ideal quando os tipos não possuem propriedades conflitantes.


Extensão com interface

Interfaces permitem herança explícita usando extends, o que deixa a intenção mais clara em modelos orientados a domínio.

interface Usuario {
nome: string;
}

interface UsuarioComId extends Usuario {
id: number;
}

Essa abordagem é útil quando você quer especializar um tipo base.


Declaration Merging com interface

O TypeScript permite que múltiplas interfaces com o mesmo nome sejam automaticamente combinadas.

interface Produto {
nome: string;
}

interface Produto {
preco: number;
}

Resultado final:

interface Produto {
nome: string;
preco: number;
}

Esse comportamento só funciona com interface e é comum em extensões de tipos globais ou bibliotecas.


Merge com sobrescrita de propriedades

Quando dois tipos possuem a mesma propriedade, mas com tipos diferentes, o uso direto do & pode gerar conflitos. A forma mais segura é remover a propriedade original antes de redefini-la.

type Produto = {
id: string;
nome: string;
};

type ProdutoResult = Omit<Produto, "id"> & {
id: number;
};

Essa técnica garante que o tipo final tenha a definição correta da propriedade sobrescrita.


Merge genérico com utilitário reutilizável

É possível criar um tipo utilitário genérico para mergear tipos de forma reutilizável.

type Merge<T, U> = Omit<T, keyof U> & U;

Uso:

type Resultado = Merge<
{ nome: string; idade: number },
{ idade: string }
>;

Nesse caso, propriedades de U sempre têm prioridade sobre T.


Comparação das abordagens

AbordagemQuando usar
Intersection (&)Tipos sem conflito
extendsHerança clara e semântica
Declaration MergingExtensões globais
Omit + &Sobrescrever propriedades
Merge genéricoCódigo reutilizável