Generics (typy ogólne) pozwalają na pisanie uniwersalnego kodu, który działa z różnymi typami, zachowując ścisłą bezpieczeństwo typów.
Składnia użycia:
function identity<T>(value: T): T { return value; } const x = identity<string>('test'); // T = string
Gdzie stosują:
Przykład z ograniczeniem typu:
function getFirst<T extends { length: number }>(arr: T): T { return arr[0]; }
Pytanie: Czy konieczne jest podawanie konkretnego typu przy wywołaniu funkcji z parametrem Generic?
Odpowiedź:
Nie jest konieczne. TypeScript sam wnioskuje (inferuje) typy na podstawie przekazanych wartości, jeśli to możliwe. Ale czasami wygodnie jest podać typ jawnie, na przykład, jeżeli z wartości typ nie jest oczywisty lub istnieje kilka opcji.
function identity<T>(value: T): T { return value; } identity(5); // T = number (auto) identity<string>('s'); // T = string (jawnie)
Historia
W projekcie e-commerce napisano generyczne repozytorium dla różnych podmiotów, ale zapomniano o ograniczeniu typu. W rezultacie do generyka mógł trafić dowolny obiekt, i pewnego razu zapisano podmiot z niekompatybilnymi polami. Typy nie ochroniły przed błędem.
Historia
Do funkcji szablonowej przekazano tablicę, oczekiwano otrzymania tablicy z typem elementów. Ale funkcja zwracała any[], ponieważ generyk nie został jawnie określony i TypeScript nie był w stanie wywnioskować typu. Błąd zauważono dopiero na produkcji.
Historia
Zaczynający programista stworzył generyczną klasę bez ograniczenia typu, używając pola, którego nie było w wszystkich typach. Kompilator nie zgłaszał błędu, ale przy dostępie do nieistniejącej właściwości cały funkcjonalność się psuła.