TypeScript infer Keyword
TypeScript infer Keyword com exemplos
Nesse artigo, vou te mostrar como podemos usar a keyword infer
para extrair os tipos dos genéricos. Vamos usar Promise
como exemplo.
type UnpackPromise<P> = ✨magic✨
UnpackPromise<Promise<string>> // <- string
UnpackPromise<Promise<number>> // <- number
UnpackPromise<Promise<boolean>> // <- boolean
TypeScripttype UnpackPromise<P> = ✨magic✨
UnpackPromise<Promise<string>> // <- string
UnpackPromise<Promise<number>> // <- number
UnpackPromise<Promise<boolean>> // <- boolean
Se P
é um subconjunto da Promise
de um T
, queremos retornar T
. Do contrário, retornamos never
, o que representa algo que nunca deve acontecer.
type UnpackPromise<P> = P extends Promise<T> ? T : never;
TypeScripttype UnpackPromise<P> = P extends Promise<T> ? T : never;
Mas isso não funciona, porque T
ainda não existe.
Vamos comparar isso com uma função e você verá o que quero dizer.
const UnpackPromise = (P) =>
P === Promise<T>
? T
: never
TypeScriptconst UnpackPromise = (P) =>
P === Promise<T>
? T
: never
P
é um argumento, mas de onde vem o T
?
Em uma função regular, você poderia resolver isso criando uma variável chamada T
. Algo como isso:
const UnpackPromise = (P) =>
P === Promise<var T>
? T
: never
TypeScriptconst UnpackPromise = (P) =>
P === Promise<var T>
? T
: never
E é aí que entra a keyword infer
. Ela funciona como uma declaração de variável.
type UnpackPromise<P> = P extends Promise<infer T> ? T : never;
TypeScripttype UnpackPromise<P> = P extends Promise<infer T> ? T : never;
Se P
é um subconjunto de uma Promise
, nós pedimos ao TypeScript para deduzir o tipo interno dessa Promise
e salvá-lo em um tipo chamado T
. Daí, nós retornamos T
.
type UnpackPromise<P> =
P extends Promise<infer T>
? T
: never
UnpackPromise<Promise<string>> // <- string
UnpackPromise<Promise<number>> // <- number
UnpackPromise<Promise<boolean>> // <- boolean
UnpackPromise<Promise<Array<Date>>> // <- Array<Date>
UnpackPromise<Promise<boolean | string>> // <- boolean | string
TypeScripttype UnpackPromise<P> =
P extends Promise<infer T>
? T
: never
UnpackPromise<Promise<string>> // <- string
UnpackPromise<Promise<number>> // <- number
UnpackPromise<Promise<boolean>> // <- boolean
UnpackPromise<Promise<Array<Date>>> // <- Array<Date>
UnpackPromise<Promise<boolean | string>> // <- boolean | string
Conclusão
As referências estão abaixo.
Tem muito mais sobre a infer
keyword, mas isso é tudo que eu consigo encaixar em um vídeo de um minuto. Se você quiser ir mais fundo no TypeScript, tenho uma série sobre TypeScript narrowing. Você pode assistir à série completa, de graça, no meu canal.
Deixe um like, tenha um ótimo dia e te vejo em breve.