Generics em JavaScript: para que servem e como usar na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que o JavaScript precisa de Generics?



O desenvolvimento em JavaScript (especialmente no ambiente Node.js) frequentemente enfrenta o problema de duplicação de código. Imagine que você precisa escrever uma função que funcione com números, strings e arrays. Sem Generics (genéricos), você escreve várias sobrecargas ou usa any, perdendo toda a magia dos tipos.



Generics é um mecanismo que permite criar componentes (funções, classes, interfaces) que trabalham com diferentes tipos de dados, mantendo a tipagem estrita. No contexto do JavaScript, os genéricos estão totalmente disponíveis através do TypeScript, mas entender seus princípios é fundamental para qualquer desenvolvedor moderno.



Neste artigo, vamos explorar para que servem os generics, como usá-los na prática em Node.js e por que isso torna seu código mais seguro e reutilizável.



1. Generics em TypeScript: a base da segurança de tipos



Embora o JavaScript puro não tenha suporte nativo a genéricos, o TypeScript (uma extensão do JS) os oferece em sua totalidade. É por isso que todos os frameworks e bibliotecas modernos para Node.js (NestJS, Express com tipos) os utilizam ativamente.



Exemplo simples: função identity



O exemplo clássico é uma função que retorna o que recebeu:



// Sem generics — usamos any (perdemos o tipo)function identity(arg: any): any {  return arg;}

// Com generic — o tipo é preservadofunction identity<T>(arg: T): T { return arg;}

// Usoconst num = identity<number>(42); // Tipo: numberconst str = identity<string>('hello'); // Tipo: string


Observe: <T> é o parâmetro de tipo. Dizemos ao TypeScript: "O tipo será informado depois". O compilador infere automaticamente o tipo, então muitas vezes podemos escrever apenas identity(42).



Por que isso é importante para Node.js?



No Node.js, você trabalha constantemente com APIs, bancos de dados e serviços externos. Generics permitem garantir que os dados cheguem exatamente no formato esperado:



// Função para trabalhar com APIasync function fetchData<T>(url: string): Promise<T> {  const response = await fetch(url);  return response.json() as Promise<T>;}

// Agora sabemos a estrutura exata da respostainterface User { id: number; name: string;}

const user = await fetchData<User>('/api/user/1');// user.name — string, user.id — número (TypeScript verifica isso)


2. Cenários práticos: trabalhando com arrays e coleções



Generics são especialmente úteis ao trabalhar com arrays e coleções de dados. Vejamos um exemplo real do Node.js — uma função de filtragem e transformação.



Função genérica para mapeamento



// Função que transforma um array de um tipo em um array de outro tipofunction mapArray<T, U>(items: T[], mapper: (item: T) => U): U[] {  return items.map(mapper);}

// Exemplo: de User, obtemos apenas os nomesinterface User { id: number; name: string; email: string;}

const users: User[] = [ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' }];

const names: string[] = mapArray(users, (user) => user.name);// names: ['Alice', 'Bob'] — tipo string[] garantido


Aqui, <T, U> são dois parâmetros de tipo. T é o tipo do array de entrada, U é o tipo do resultado. Isso oferece máxima flexibilidade sem perda de tipos.



Classe genérica para pilha



No Node.js, estruturas de dados são frequentemente necessárias. Vamos criar uma pilha com segurança de tipos:



class Stack<T> {  private items: T[] = [];

pu

Blogs

Book Recommendations