TypeScript Generics med exempel

Generika från TypeScript är en kraftfull funktion som låter dig skapa återanvändbara och typsäkra komponenter. Generika ger ett sätt att skapa klasser, funktioner och gränssnitt som fungerar med en mängd olika typer samtidigt som en stark typsäkerhet bibehålls. Den här artikeln kommer att introducera dig till generika och demonstrera hur du använder dem med praktiska exempel.

Förstå generika

Generics gör att du kan definiera en komponent med en platshållare för den typ som den fungerar på. Istället för att ange en konkret typ använder du en generisk typparameter som kan ersättas med vilken typ som helst när komponenten används.

Grundläggande syntax

Den grundläggande syntaxen för att definiera en generisk typ är att använda vinkelparenteser <> med ett typparameternamn. Här är ett enkelt exempel:

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

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

I det här exemplet är identitet en generisk funktion som tar en parameter värde av typen T och returnerar ett värde av samma typ. Typparametern T ersätts med den faktiska typen när funktionen anropas.

Generika med klasser

Generika kan också användas med klasser för att skapa flexibla och återanvändbara datastrukturer. Här är ett exempel på en generisk klass:

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

I det här exemplet är klassen Box definierad med en generisk typparameter T. Klassen har en privat egenskap värde av typen T och en metod getValue som returnerar värdet av typen T.

Generika med gränssnitt

Generika kan användas med gränssnitt för att skapa flexibla och typsäkra gränssnitt. Här är ett exempel:

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

I det här exemplet är Pair-gränssnittet definierat med två generiska typparametrar T och U. Gränssnittet representerar ett par värden med typerna T respektive U.

Generika i funktioner

Generika kan användas i funktioner för att hantera flera typer med bibehållen typsäkerhet. Här är ett exempel på en generisk funktion som fungerar med arrayer:

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]

I det här exemplet tar funktionen reverseArray en array av typen T och returnerar en omvänd array av samma typ. Typparametern T säkerställer att funktionen fungerar med arrayer av vilken typ som helst samtidigt som typsäkerheten bibehålls.

Restriktioner för generika

Ibland kan du behöva införa begränsningar för den generiska typparametern för att säkerställa att den har vissa egenskaper. Detta görs med hjälp av begränsningar:

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

I det här exemplet är logLength-funktionen begränsad till typer som har egenskapen length. Detta tillåter funktionen att acceptera strängar och arrayer men inte siffror eller andra typer utan en length egenskap.

Slutsats

Generika i TypeScript ger ett kraftfullt sätt att skapa flexibla och återanvändbara komponenter samtidigt som en stark typsäkerhet bibehålls. Genom att förstå och använda generika kan du skriva mer generisk och anpassningsbar kod, vilket förbättrar den övergripande kvaliteten och underhållbarheten för dina TypeScript-applikationer.

Experimentera med generika i dina projekt för att se deras fördelar i praktiken och förbättra dina TypeScript-programmeringsfärdigheter.