0Pricing
TypeScript Academy · Aula

Tipos Condicionais Distributivos

Controle como os condicionais são distribuídos pelas uniões.

Tipos Condicionais Distributivos é uma aula grátis de TypeScript Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de TypeScript Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de TypeScript Academy inclui 4 aulas no total.

Um comportamento surpreendente

Os tipos condicionais têm uma regra especial: quando o tipo verificado é um parâmetro de tipo nu e você passa uma união, o condicional é distribuído separadamente sobre cada membro e, depois, os resultados são unidos.

Essa é a base de Exclude, Extract e de muitos utilitários.

type ToArray<T> = T extends unknown ? T[] : never;

type A = ToArray<string | number>;
// string[] | number[]  (NOT (string | number)[])

O que significa "nu"

"Nu" significa que o parâmetro de tipo aparece sozinho no lado esquerdo de extends, sem estar envolvido por outro tipo. A distribuição só acontece com parâmetros nus.

type Naked<T> = T extends string ? "y" : "n";
// T is naked -> distributes over unions

Distribuição passo a passo

Para ToArray<string | number>, o compilador avalia cada membro:

  • ToArray<string> = string[]
  • ToArray<number> = number[]

Depois, ele os une: string[] | number[].

type R = ToArray<boolean>;
// boolean is true | false, so:
// true[] | false[]

Filtrando uma união

A distribuição facilita a filtragem. Mapeie os membros indesejados para never; never desaparece de uma união, deixando apenas os membros mantidos.

type Strings<T> = T extends string ? T : never;

type A = Strings<string | number | boolean>; // string

never desaparece nas uniões

Um fato importante: X | never é simplificado para X. Portanto, quando um ramo distribuído produz never, esse membro é efetivamente removido da união final.

type A = string | never;        // string
type B = "a" | never | "b";     // "a" | "b"

Desativando a distribuição

Às vezes, você não quer distribuição, por exemplo, ao comparar uma união inteira como uma única unidade. Envolva os dois lados em uma tupla de um elemento: [T] extends [U]. Agora T não é mais nu, portanto a distribuição fica desativada.

type IsNever<T> = [T] extends [never] ? true : false;

type A = IsNever<never>;  // true
type B = IsNever<string>; // false

Por que o envolvimento funciona

Ao colocar [T] à esquerda, o tipo verificado é uma tupla, não o parâmetro isolado. A regra especial de distribuição deixa de se aplicar, então a união é testada como um todo.

type AllStrings<T> = [T] extends [string] ? true : false;

type A = AllStrings<"a" | "b">;     // true
type B = AllStrings<"a" | number>;  // false

Distribuído versus não distribuído

Compare diretamente as duas formas. A versão nua verifica cada membro; a versão envolvida verifica a união como um único tipo.

type Distributed<T> = T extends string ? true : false;
type Wrapped<T> = [T] extends [string] ? true : false;

type A = Distributed<string | number>; // boolean (true | false)
type B = Wrapped<string | number>;     // false

Parte interna de Exclude

O tipo integrado Exclude<T, U> remove de T qualquer membro atribuível a U. Ele é apenas um condicional distributivo que mapeia os membros correspondentes para never.

type MyExclude<T, U> = T extends U ? never : T;

type A = MyExclude<"a" | "b" | "c", "b">; // "a" | "c"

Parte interna de Extract

Extract<T, U> é o inverso: mantém apenas os membros atribuíveis a U. A mesma distribuição, com ramos opostos.

type MyExtract<T, U> = T extends U ? T : never;

type A = MyExtract<"a" | "b" | "c", "a" | "c">; // "a" | "c"

Poder prático

A distribuição permite transformar cada membro de uma união em uma única expressão: criar vetores de cada membro, acrescentar um prefixo a cada cadeia de caracteres ou filtrar por formato. Combinada com [T] extends [U] para verificações da união inteira, ela permite controlar exatamente quando a distribuição é acionada.

Notação: o TypeScript real escreve tipos literais de modelo com cadeias delimitadas por acentos graves que contêm lacunas com cifrão e chaves. Nestes trechos, mostramos esse padrão como Tpl<...>, listando cada parte na ordem; por exemplo, um modelo com acento grave que corresponde ao prefixo literal seguido de Rest aparece como Tpl<'prefix', infer Rest>.

type Prefix<T extends string> = T extends unknown ? Tpl<'id_', T> : never;
// Tpl<'id_', T> is the template literal type joining 'id_' with each T

type A = Prefix<'a' | 'b'>; // 'id_a' | 'id_b'

Verificação rápida

Teste sua compreensão dos condicionais distributivos.

Recapitulação

Os tipos condicionais distributivos são o mecanismo por trás dos utilitários de união.

  • Um T extends U ? nu é distribuído sobre cada membro da união.
  • Ramos que retornam never filtram os membros.
  • [T] extends [U] desativa a distribuição para verificações da união inteira.
  • Exclude e Extract são pequenos condicionais distributivos.

O próximo é o Curso 22: aritmética no sistema de tipos.

Perguntas Frequentes

A aula “Tipos Condicionais Distributivos” é grátis?

Sim — o texto completo de “Tipos Condicionais Distributivos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de TypeScript Academy, atualize para CoddyKit PRO. O curso de TypeScript Academy inclui 4 aulas no total.

O que vou aprender em “Tipos Condicionais Distributivos”?

Controle como os condicionais são distribuídos pelas uniões. Você pratica TypeScript Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar TypeScript Academy?

Nenhuma experiência prévia é necessária. TypeScript Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Tipos Condicionais Distributivos”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de TypeScript Academy?

Sim. Cada aula de TypeScript Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Tipos como Linguagem de Computação
  2. Condicionais no Nível de Tipos
  3. Recursão no Nível de Tipos
  4. Tipos Condicionais Distributivos
← Voltar para TypeScript Academy