Generic Functions
Tipos genéricos permitem usar Tipos como variáveis em outros tipos.
Meta
Tentaremos manter este exemplo leve. Você pode fazer
muita coisa com tipos genéricos e é provável que veja algum código bem
complicado usando tipos genéricos em algum ponto - mas isso
não significa que tipos genéricos são complicados.
Vamos começar com um exemplo onde envolveremos um objeto de entrada
em um array. Só vamos nos importar com uma variável neste caso:
o tipo que foi passado como argumento:
// Nota: é comum ver Tipo ser referido como T. Isso é
culturalmente similar a como as pessoas usam i em um loop for
para representar índice. T normalmente representa Tipo (Type), então
usaremos o nome completo para maior clareza
Nossa função usará inferência para sempre manter o tipo
passado como argumento igual ao tipo retornado (porém
envolvido em um array)
function envolverEmArray
// Podemos verificar que isso funciona como esperado ao checar
se podemos atribuir um array de strings a uma função que
deveria ser um array de objetos
const stringArray = envolverEmArray("hello generics");
const numberArray = envolverEmArray(123);
// Você também pode evitar a inferência adicionando
o tipo você mesmo:
const naoArrayDeStrings: string[] = envolverEmArray({});
// envolverEmArray permite que qualquer tipo seja usado, porém existem
casos onde você precisa permitir apenas um subconjunto de tipos.
Nesses casos você pode dizer que o tipo deve estender um
tipo específico.
const arrayDeStrings2 = envolverEmArray
// Esta função recebe um conjunto de objetos que possuem uma função
para desenhar na tela
interface Desenhavel {
desenhar: () => void;
}
// Tipos genéricos podem começar a parecer complicados quando você tem
múltiplas variáveis. Aqui está um exemplo de uma função de caching
que permite que você tenha diferentes conjuntos de tipos de entrada
e caches.
function renderizarNaTela
// Este é o mesmo exemplo que acima, porém com um parâmetro extra.
Nota: para fazê-lo funcionar, porém, tivemos que usar any. Isso
pode ser resolvido usando uma interface genérica
interface HostDeCache {
salvar: (a: any) => void;
}
function adicionarObjetoAoCache
// Agora quando o HostDeCacheGenerico é usado, você deve dizer
a dele qual é o TipoDeConteudo
interface HostDeCacheGenerico
// O exemplo acima é bem intenso em termos de sintaxe. Porém,
isso provê uma segurança maior. Essas são escolhas que
agora você tem conhecimento para fazer. Quando for prover APIs
a outras pessoas, tipos genéricos oferecem um jeito flexível de permitir
que elas usem seus próprios tipos sem ter que inferir seu código por completo.
Para mais exemplos de tipos genéricos com classes e interfaces:
example:advanced-classes
example:typescript-with-react
https://www.typescriptlang.org/docs/handbook/generics.html
function adicionarObjetoTipadoAoCache