Se vocĂȘ quer levar seu conhecimento de TypeScript para o prĂłximo nĂvel, vocĂȘ precisa entender sobre Conditional Types (Tipos Condicionais). Aprender isso com certeza irĂĄ te colocar na frente da maioria dos desenvolvedores Typescript, jĂĄ que poucos conhecem sobre.
Antes de tudo: Conceitos fundamentais
Para entender os Conditional Types, Ă© necessĂĄrio dominar trĂȘs conceitos do TypeScript:
- Generics
extends- TernĂĄrio
1. Generics
Leia esse outro artigo que fiz caso vocĂȘ nĂŁo saiba o que Ă©:
2. Extends
Usado para impor que um tipo herda (ou estende) outro tipo.
interface A {
name: string;
}
// B tem todas as propriedades de A
interface B extends A {
age: number;
}
Nos Conditional Types, o extends Ă© usado como parte de uma condição (nĂŁo Ă© a mesma funcionalidade do examplo, mas vocĂȘ irĂĄ entender mais pra frente)
3. Operador TernĂĄrio
Muito conhecido de outras linguagens, o ternårio permite retornar valores diferentes baseado em uma condição:
condição ? valorSeVerdadeiro : valorSeFalso
Esses trĂȘs elementos formam a base dos Conditional Types.
O que sĂŁo Conditional Types?
Um Conditional Type permite criar um tipo baseado em uma condição lógica entre dois tipos.
A base dos Conditional Types:
Usar um Conditional Types, nada mais Ă© do que vocĂȘ colocar uma verificação no seu tipo, onde vocĂȘ usa extends para verificar e usa o ternĂĄrio para retornar o tipo dependendo da verificação.
type Teste<T> = T extends string ? true : false;
type A = Teste<string>; // true
type B = Teste<number>; // false
Aqui, o tipo Teste verifica se T Ă© uma string. Se sim, retorna true, senĂŁo false.
Para simplificar, vocĂȘ pode imaginar o seguinte:
-
T extends string=>T === string -
... ? true : false;=>if(...) { return true } else { return false }
A syntax pode parecer complicada, mas vocĂȘ pode imaginar como se fosse vĂĄrios if e else.
Usos prĂĄticos com Conditional Types
1. Remover tipos null ou undefined
O TypeScript jĂĄ possui o tipo NonNullable, mas ele pode ser recriado usando Conditional Types:
type NonNullableCustom<T> = T extends null | undefined ? never : T;
type A = NonNullableCustom<string | null>; // string
Nesse caso, para "excluir" um tipo, vocĂȘ retorna o tipo never.
2. Recriando o tipo Extract
O TypeScript jĂĄ possui o tipo Extract, mas ele pode ser recriado usando Conditional Types:
type ExtractCustom<T, U> = T extends U ? T : never;
Por exemplo:
type A = ExtractCustom<string | number, string>; // string
Nesse caso, vocĂȘ pode ver como Ă© possĂvel passar vĂĄrios parĂąmetros genĂ©ricos e usa-los nas condiçÔes.
Recursividade com Conditional Types
Como exemplo, suponha que vocĂȘ quer extrair qual Ă© o tipo de um array. No Typescript, vocĂȘ pode usar [number] para accessar o tipo do array.
type ArrayValue<T extends any[]> = T[number];
type A = ArrayValue<string[]>; // => string
// Mesma coisa que fazer "string[][number]" => string
Mas esse exemplo tem um problema, porque ele não funciona para arrays de multiplas dimensÔes:
type ArrayValue<T extends any[]> = T[number];
type A = ArrayValue<string[][]>; // => string[], mas era para ser apenas string
E Ă© ai que entra o Conditional Types para resolver esse problema.
Porque no Conditional Types, vocĂȘ pode chamar o prĂłprio tipo recursivamente
type DeepArrayValue<T> = T extends any[] // verifica se Ă© um array qualquer
? DeepArrayValue<T[number]> // extrai o tipo do array e passa de novo para o prĂłprio tipo
: T; // retorna o tipo quando ele nĂŁo Ă© mais um array
type A = DeepArrayValue<string[][][]>; // string
VocĂȘ poderia "traduzir" o cĂłdigo a cima como se fosse um if e else da seguinte forma:
function DeepArrayValue(T) {
if(T === qualquer_array) { // verifica se Ă© um array qualquer
const tipo_do_array = T[number] // extrai o tipo do array
return DeepArrayValue(tipo_do_array) // chama de novo a função com o tipo extraido
} else {
return T // retorna o tipo quando ele nĂŁo Ă© mais um array qualquer
}
}
Para acabar com a recursividade, vocĂȘ acaba retornando o prĂłprio T quando ele nĂŁo Ă© mais um "array qualquer".
ConsideraçÔes Finais
Conditional Types Ă© extremamente poderosos no TypeScript e com ele foi criado a maioria dos tipos jĂĄ existentes (como o NonNullable e Extract que vimos anteriormente)
NĂŁo vai ser todos os dias que vai criar um Conditional Types do zero, mas pode ter certeza que vocĂȘ vai usar bastante algum tipo jĂĄ existente do Typescript que usa ele e por isso Ă© sempre bom entender como funciona o Conditional Types.
Esse artigo foi baseado no meu vĂdeo: Apenas 1% dos devs sabem disso no TypeScript
Se tiver dĂșvidas ou sugestĂ”es, deixe nos comentĂĄrios!
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.