Typy generyczne i stany nielegalne w TypeScript
Na ostatnim spotkaniu naszego frontend dev community, Rafał opowiadał o kodzie, który napisał w RST ponad 4 lata temu. Próba czasu pokazała, że kod jest dobrze przemyślany, dlatego warto było do niego wrócić. Była to świetna okazja, aby wykorzystać kod jako przykład pracy z typami generycznymi w TypeScript.
Podczas spotkania analizowaliśmy wspomniany kawałek kodu, który odpowiadał za pobieranie danych. Niby nic wielkiego prawda? Cóż, cała aplikacja opiera się na widokach listy oraz szczegółów. Jest to najważniejsza część aplikacji.
Typy generyczne w TypeScript
Cały system bazuje w głównej mierze na react-redux oraz RxJS, który służył do tworzenia asynchroniczności w store. Klient wymagał od nas 2 rzeczy: szybkiego czasu reakcji, który zrealizowaliśmy przez cache oraz ponawiania requestów, które zakończyły się błędem.
Generyczność pozwoliła nam na wykonanie jednego systemu do obsługi wszystkich list i tabel w dokładnie ten sam sposób! Obyło się bez powielania kodu odnośnie cache czy ponawiania requestów.
Jak działa system? Komponent w react wykorzystuje hooka, który odpowiada za pobieranie danych z store lub wysłanie akcji do store w celu pobrania ich z backendu. Wysłany event trafia do RxJS, który komunikuje się z serwisem wykonującym odpowiednie zapytanie, wybierając serwis dedykowany dla konkretnej listy. Dane trafiają ponownie do RxJS, a na ich podstawie jest tworzony event do skonsumowania przez reducer.
W obecnych czasach do tego typu funkcji warto rozważyć użycie react-query jednak 4 lata temu nie było tego typu rozwiązań. I całe szczęście, bo mogliśmy wykorzystać kod do omówienia tego jak działają typy generyczne w TypeScript!
Stany nielegalne w TypeScript
Drugą część spotkania poświęciliśmy na zapoznanie z tematem stanów nielegalnych w TypeScript, a naturalnie wynikającym z tego tematem było modelowanie domeny biznesowej. Typy, które oferuje nam TypeScript pozwalają na dobre odwzorowanie wymagań biznesowych w kodzie projektu, a dzięki zrozumieniu tematu stanów nielegalnych nasz kod będzie czystszy i mniej podatny na błędy.
Stany nielegalne możemy łatwo zobrazować interfejsem, który modeluje funkcjonalność w sposób tak elastyczny, że umożliwia tworzenie obiektów spełniających ten interfejs w sposób trudny do wytłumaczenia w kontekście aplikacji.
Omówiony zakres materiału, bez wnikania w szczegóły, możemy oprzeć na prostym przykładzie. Wyobraźmy sobie taki kontrakt stanu ładowania odpowiedzi z serwisu:
W skrajnym przypadku możemy utworzyć obiekt spełniający powyższy interfejs:
Ciężko określić po zawartości tego obiektu, w jakim aktualnie stanie jest ładowanie, prawda?
Z pomocą przychodzi nam drobny refactoring i unia obiektów, które definiują dozwolone stany:
Na temat modelowania domeny biznesowej opowiedzieliśmy sobie na przykładzie interfejsu użytkownika, który w danym kontekście użycia może występować w dwóch typach wyróżniających się specyficzną grupą pól. Możemy sobie wyobrazić na podstawie powyższego przykładu jak zamodelować interfejs spełniający reguły biznesowe pozwalający przy okazji na tworzenie nielegalnych stanów.
W takich wypadkach z pomocą przychodzi wydzielenie z obu przypadków biznesowych części pokrywających się pól do ogólnego interfejsu i przygotowanie dedykowanych pod przypadki biznesowe typów rozszerzających ten interfejs. Unia przygotowanych typów definiuje nam końcowy interfejs, który spełnia reguły biznesowe i jest bezpieczny pod kątem nielegalnych stanów.
Źródła:
https://frontlive.pl/blog/typescript-modelowanie-domeny
https://khalilstemmler.com/articles/typescript-domain-driven-design/make-illegal-states-unrepresentable
Masz pytania? Koniecznie napisz!
poznaj bliżej nas i nasze wartości