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 unionsDistribuiçã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>; // stringnever 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>; // falsePor 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>; // falseDistribuí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>; // falseParte 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
neverfiltram os membros. [T] extends [U]desativa a distribuição para verificações da união inteira.ExcludeeExtractsã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
- Tipos como Linguagem de Computação
- Condicionais no Nível de Tipos
- Recursão no Nível de Tipos
- Tipos Condicionais Distributivos