Genéricos TypeScript com Exemplos

Os genéricos do TypeScript são um recurso poderoso que permite que você crie componentes reutilizáveis ​​e com segurança de tipo. Os genéricos fornecem uma maneira de criar classes, funções e interfaces que funcionam com uma variedade de tipos, mantendo uma forte segurança de tipo. Este artigo apresentará os genéricos e demonstrará como usá-los com exemplos práticos.

Compreendendo os Genéricos

Genéricos permitem que você defina um componente com um placeholder para o tipo em que ele opera. Em vez de especificar um tipo concreto, você usa um parâmetro de tipo genérico que pode ser substituído por qualquer tipo quando o componente é usado.

Sintaxe básica

A sintaxe básica para definir um tipo genérico é usar colchetes angulares <> com um nome de parâmetro de tipo. Aqui está um exemplo simples:

function identity(value: T): T {
  return value;
}

const stringIdentity = identity("Hello"); // string
const numberIdentity = identity(123); // number

Neste exemplo, identity é uma função genérica que recebe um parâmetro value do tipo T e retorna um valor do mesmo tipo. O parâmetro de tipo T é substituído pelo tipo real quando a função é chamada.

Genéricos com Classes

Genéricos também podem ser usados ​​com classes para criar estruturas de dados flexíveis e reutilizáveis. Aqui está um exemplo de uma classe genérica:

class Box {
  private value: T;

  constructor(value: T) {
    this.value = value;
  }

  getValue(): T {
    return this.value;
  }
}

const stringBox = new Box("TypeScript");
console.log(stringBox.getValue()); // Output: TypeScript

const numberBox = new Box(42);
console.log(numberBox.getValue()); // Output: 42

Neste exemplo, a classe Box é definida com um parâmetro de tipo genérico T. A classe tem uma propriedade privada value do tipo T e um método getValue que retorna o valor do tipo T.

Genéricos com Interfaces

Genéricos podem ser usados ​​com interfaces para criar interfaces flexíveis e de tipo seguro. Aqui está um exemplo:

interface Pair<T, U> {
  first: T;
  second: U;
}

const pair: Pair<string, number> = {
  first: "Age",
  second: 30
};

console.log(pair.first); // Output: Age
console.log(pair.second); // Output: 30

Neste exemplo, a interface Pair é definida com dois parâmetros de tipo genérico T e U. A interface representa um par de valores com tipos T e U, respectivamente.

Genéricos em Funções

Genéricos podem ser usados ​​em funções para manipular vários tipos, mantendo a segurança do tipo. Aqui está um exemplo de uma função genérica que funciona com arrays:

function reverseArray(items: T[]): T[] {
  return items.reverse();
}

const reversedStringArray = reverseArray(["one", "two", "three"]);
console.log(reversedStringArray); // Output: ["three", "two", "one"]

const reversedNumberArray = reverseArray([1, 2, 3]);
console.log(reversedNumberArray); // Output: [3, 2, 1]

Neste exemplo, a função reverseArray pega um array do tipo T e retorna um array invertido do mesmo tipo. O parâmetro de tipo T garante que a função funcione com arrays de qualquer tipo, mantendo a segurança do tipo.

Restrições aos Genéricos

Às vezes, você pode precisar impor restrições ao parâmetro de tipo genérico para garantir que ele tenha certas propriedades. Isso é feito usando restrições:

function logLength(item: T): void {
  console.log(item.length);
}

logLength("Hello, TypeScript"); // Output: 16
logLength([1, 2, 3]); // Output: 3
// logLength(123); // Error: number does not have a length property

Neste exemplo, a função logLength é restrita a tipos que têm uma propriedade length. Isso permite que a função aceite strings e arrays, mas não números ou outros tipos sem uma propriedade length.

Conclusão

Genéricos em TypeScript fornecem uma maneira poderosa de criar componentes flexíveis e reutilizáveis, mantendo ao mesmo tempo uma forte segurança de tipo. Ao entender e utilizar genéricos, você pode escrever código mais genérico e adaptável, melhorando a qualidade geral e a manutenibilidade de seus aplicativos TypeScript.

Experimente genéricos em seus projetos para ver seus benefícios em ação e aprimorar suas habilidades de programação em TypeScript.