Typy generyczne TypeScript z przykładami

Generyki TypeScript to potężna funkcja, która umożliwia tworzenie komponentów wielokrotnego użytku i bezpiecznych pod względem typu. Generyki umożliwiają tworzenie klas, funkcji i interfejsów, które działają z różnymi typami, zachowując jednocześnie silne bezpieczeństwo typu. Ten artykuł wprowadzi Cię do generyków i pokaże, jak ich używać, na praktycznych przykładach.

Zrozumienie generyków

Generyki umożliwiają zdefiniowanie komponentu z symbolem zastępczym dla typu, na którym działa. Zamiast określać konkretny typ, używasz parametru typu generycznego, który można zastąpić dowolnym typem, gdy komponent jest używany.

Podstawowa składnia

Podstawowa składnia definiowania typu generycznego polega na użyciu nawiasów kątowych <> z nazwą parametru typu. Oto prosty przykład:

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

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

W tym przykładzie identity jest funkcją generyczną, która przyjmuje parametr value typu T i zwraca wartość tego samego typu. Parametr typu T jest zastępowany rzeczywistym typem, gdy funkcja jest wywoływana.

Generyki z klasami

Generyki można również stosować z klasami, aby tworzyć elastyczne i wielokrotnego użytku struktury danych. Oto przykład klasy generycznej:

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

W tym przykładzie klasa Box jest zdefiniowana z parametrem typu generycznego T. Klasa ma prywatną właściwość value typu T i metodę getValue, która zwraca wartość typu T.

Generyki z interfejsami

Generyki można stosować z interfejsami, aby tworzyć elastyczne i bezpieczne pod względem typu interfejsy. Oto przykład:

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

W tym przykładzie interfejs Pair jest zdefiniowany z dwoma parametrami typu generycznego T i U. Interfejs reprezentuje parę wartości z typami T i U, odpowiednio.

Typy generyczne w funkcjach

Generyki mogą być używane w funkcjach do obsługi wielu typów przy zachowaniu bezpieczeństwa typu. Oto przykład funkcji generycznej, która działa z tablicami:

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]

W tym przykładzie funkcja reverseArray przyjmuje tablicę typu T i zwraca odwróconą tablicę tego samego typu. Parametr typu T zapewnia, że ​​funkcja działa z tablicami dowolnego typu, zachowując bezpieczeństwo typu.

Ograniczenia dotyczące typów generycznych

Czasami może być konieczne nałożenie ograniczeń na parametr typu generycznego, aby upewnić się, że ma on określone właściwości. Robi się to za pomocą ograniczeń:

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

W tym przykładzie funkcja logLength jest ograniczona do typów, które mają właściwość length. Dzięki temu funkcja może akceptować ciągi znaków i tablice, ale nie liczby lub inne typy bez właściwości length.

Wniosek

Generyki w TypeScript zapewniają potężny sposób tworzenia elastycznych i wielokrotnego użytku komponentów przy jednoczesnym zachowaniu silnego bezpieczeństwa typu. Rozumiejąc i wykorzystując generyki, możesz pisać bardziej generyczny i adaptowalny kod, poprawiając ogólną jakość i łatwość utrzymania aplikacji TypeScript.

Eksperymentuj z typami generycznymi w swoich projektach, aby zobaczyć ich zalety w praktyce i udoskonalić swoje umiejętności programowania w języku TypeScript.