O que são Generics e como eles funcionam?
You have actually seen a generic type in a previous lesson:
Array<string>. Mas você geralmente usará tipos genéricos em funções. De fato, eles podem ser considerados como um parâmetro especial que você fornece a uma função para controlar o comportamento da definição de tipo da função.
Vamos voltar ao nosso exemplo anterior de uma função para obter um valor aleatório de um array:
const getRandomValue = (array: string[]): string => {
return array[Math.floor(Math.random() * array.length)];
}
Nossa função aceita um array de strings e retorna uma string. Mas e se quisermos passar um array de números e retornar um número?
Você pode usar um tipo união:
const getRandomValue = (array: (string|number)[]): (string|number) => {
return array[Math.floor(Math.random() * array.length)];
}
const val = getRandomValue([1, 2, 4])
Mas com essa abordagem, mesmo que tenhamos passado um array de apenas números, o TypeScript determina que a variável val pode ser um número OU uma string.
Em vez disso, você pode definir um tipo genérico para a função:
const getRandomValue = <T>(array: T[]): T => {
return array[Math.floor(Math.random() * array.length)];
}
const val = getRandomValue([1, 2, 4])
Existem alguns componentes importantes no nosso novo exemplo. Primeiro, a sintaxe <T> informa ao TypeScript que você está definindo um tipo genérico T para a função. T é um nome comum para tipos genéricos, mas você pode realmente nomeá-lo como quiser (dentro das convenções de variáveis do JavaScript).
Então, informamos ao TypeScript que o parâmetro array é um array de valores que correspondem ao tipo genérico, e que o valor retornado é um único elemento desse mesmo tipo. Isso permite que o TypeScript detecte corretamente que val será um número, porque o array que passamos consiste exclusivamente de números.
Mas e as funções que você não controla? Vamos dar uma olhada no método document.querySelector():
const email = document.querySelector("#email");
console.log(email.value);
Porque estamos consultando com um seletor de ID, o TypeScript não sabe que tipo de elemento estamos consultando. Ele sabe que é um Element de algum tipo, mas nossa tentativa de acessar a propriedade value gerará um erro porque a interface do elemento de nível superior não possui essa propriedade.
Felizmente, podemos passar um argumento de tipo para a chamada da função:
const email = document.querySelector<HTMLInputElement>("#email");
console.log(email.value);
Note como estamos usando novamente a sintaxe de colchetes angulares (<HTMLInputElement>), mas desta vez em uma chamada de função. Isso informa ao TypeScript que o elemento que esperamos encontrar será um elemento input e não recebemos mais um erro na propriedade value porque elementos input possuem essa propriedade. Claro, querySelector pode retornar null se um elemento não for encontrado e o TypeScript gerará um erro de compilação aqui porque não tratamos esse caso.
Mas você vai aprender sobre isso na próxima lição.Este módulo não possui perguntas. Marque como concluído.