TypeScript – pierwsze kroki. Interfejsy i klasy generyczne.

Ostatnim razem przedstawiłem ideę typów generycznych i pokazałem jak wykorzystywać je w funkcjach. Jednak funkcje to nie jedyne mechanizmy, mające możliwość korzystania z typów generycznych. Funkcjonalność ta może być również wykorzystana przy interfejsach oraz klasach.

W dzisiejszym poście zaprezentuję jak tworzyć interfejsy oraz klasy w połączeniu z typami generycznymi. Ta potężna kombinacja daje programistom TypeScript naprawdę spore możliwości.

Programowanie w TypeScript

Główny cel używania typów generyczny wraz z interfejsami i klasami jest taki sam jak w przypadku funkcji. Chcę pisać kod, który mogę używać w różnych warunkach. Innymi słowy, chcę uniknąć powtarzania tego samego kodu dla różnych typów danych. Brzmi to fajnie, ale zdaję sobie sprawę, że przykłady z funkcjami mogły nie wyglądać przekonująco. Myślę jednak, że w przypadku klas i interfejsów, każdy będzie w stani9e zobaczyć prawdziwy potencjał tego rozwiązania.

Przejdę od razu do przykładu. Oto interfejs zaimplementowany przy użyciu generyków:

Struktura powinna wyglądać już znajomo. Wygląda to jak zwykły interfejs z jedną różnicą. Po jego nazwie podaję listę parametrów typów. Tak jak w przypadku funkcji, znajdują się one wewnątrz ostrych nawiasów. I tak jak w przypadku funkcji, rzadko jest ich więcej niż jeden 😉 . Wewnątrz interfejsu, wszystkie te elementy, które chcę aby przybrały typ generyczny, oznaczam literką T (powtarzam: wielkie T to przyjęty zapis, jednak parametry typowe można nazywać dowolnie, z godnie z JSowymi konwencjami nazw).

Pierwszy element animalList będzie przechowywał tablicę elementów typu T. Drugi element, metoda getLastAnimal, zwraca obiekt/zmienną typu T. Natomiast ostatni element, metoda addAnimal, przyjmuje obiekt/zmienną typu T. Warto w tym miejscu zwrócić uwagę na to jak zapisałem typ pola animalList. To nic innego jak klasa Array o typie generycznym 🙂 . To może nie być jeszcze do końca jasne, ale za chwile powinno się wyklarować.

Sam w sobie interfejs ten nie jest specjalnie użyteczny. mógłbym stworzyć obiekt typu HandlerInterface, wyglądałoby to tak:

Tak zadeklarowana zmienna, przechowywać może dane typu HandlerInterface, który obsługuje tylko liczby. Oczywiście, można stworzyć drugi obiekt, który obsługiwać będzie inny typ danych, na tym polega piękno typów generycznych 🙂 . Nic nie stoi na przeszkodzie aby stworzyć interfejs, który sprawdziłby się w takim zadaniu. Jednak w moim przykładzie nie ma to większego sensu.

Znacznie lepszym rozwiązaniem byłyby zaimplementowanie go do klasy. Na przykład w taki sposób:

Klasa AnimalHandler implementuje interfejs HandlerInterface. Jeśli implementowany interfejs korzysta z typów generycznych, klasa też musi z nich korzystać. W tym wypadku T odnosi się do tego samego typu i tak będzie traktowany.

Nic nie stoi na przeszkodzie, aby typy generyczne dodawać do klas bez konieczności korzystania z interfejsu. Gdyby z powyższego przykładu wyciąć fragment implements HandlerInterface, kod działał by dokładnie tak samo. Ja jednak chcę skorzystać z interfejsu.

Klasa AnimalHandler w konstruktorze przyjmuje jeden argument, tablicę elementów typu T, która przypisana jest do publicznego pola animalList. Ponadto posiada dwie metody: getLastAnimal, która zwraca ostatni element tablicy animalList, oraz addAnimal, które przyjmuje argument typu T i dodaje go do tablicy animalList.

Od razu widać jak dobrze to wszystko współgra ze sobą. Żadne zasady obsługi typów nie są naginane a jednak taka klasa jest już naprawdę wszechstronna.

Załóżmy, że w programie mamy klasy Cat oraz Dog definiowane w taki sposób:

Teraz mogę tworzyć instancje klasy AnimalHandler Tak aby obsługiwały zarówno obiekty jednego jak i drugiego typu:

Przedstawione tu rozwiązania, dają programiście ogromne możliwości. Typy generyczne to zdecydowanie jeden z ciekawszych elementów TypeScriptu. A to jeszcze nie koniec, czasem potrzebna jest możliwość ograniczenia generyków. Kolejny post poświęcę właśnie temu zagadnieniu.

Jeżeli chcesz być na bieżąco z postami na blogu zachęcam do polubienia mojej strony na facebooku. Zawsze zamieszczam tam informacje o wszystkich nowościach. Jest to też dobre miejsce na kontakt ze mną. Na wszystkie pytania zawsze odpowiem :).

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *