Techniki Zaawansowane
2 godz. 35 min · Typescript · Full-stack i Programowanie
Adam GospodarczykZacznijmy od tego, że JavaScript jest dynamicznie typowany. Oznacza to, że typy zmiennych mogą się zmieniać w czasie wykonywania programu, a my nie mamy nad nimi kontroli. A po co nam ta kontrola? Między innymi po to, aby przypadkowo nie dodać typu number do string lub przekazać do funkcji nieprawidłowe danych. Ogromną zaletą jest to, że o tego typu błędach dowiadujemy się już na etapie pisania kodu a nie dopiero w trakcie jego wykonywania... na produkcji.
TypeScript umożliwia stosunkowo prostą migrację istniejących projektów JavaScript. W kursie na przykładzie zostały omówione trzy strategie, dzięki którym jesteśmy w stanie dodać statyczne typowanie do istniejącego kodu. W procesie migracji najważniejsze jest to, że przepisywanie kodu jesteśmy w stanie uzależnić również od poziomu naszej wiedzy na temat TypeScriptu i stopniowo dodawać kolejne elementy.
Na pierwszy rzut oka można uznać, że TypeScript tylko dodaje nam pracy, wymuszając dodatkową konfigurację oraz opisywanie typów. Mało tego zwiększa barierę wejścia w projekt dla mniej doświadczonych programistów. Trudno temu zaprzeczyć ALE - korzyści płynące ze statycznego typowania które wpływają na zmniejszenie liczby błędów oraz wykrywanie ich nawet na poziomie pisania kodu, oszczędzają czas który normalnie poświęcilibyśmy na późniejsze debugowanie aplikacji. Poza tym zwiększenie stabilności aplikacji daje szerokie korzyści biznesowe, które wielokrotnie wynagradzają nam czas wymagany na pisanie dodatkowej składni.
JavaScript jest językiem dynamicznie typowanym. W trakcie wykonywania programu, zmienne mogą zmieniać swój typ a my nie zawsze mamy nad tym świadomą kontrolę. Tylko ... po co nam ta kontrola? Główną zaletą statycznego typowania jest to aby uniknąć sytuacji w których przypadkowo przypisujemy tekst do zmiennej która powinna zawierać liczbę lub sytuacji w której przekazujemy do funkcji nieprawidłowe dane. Taki rodzaj pomyłek generuje błędy odniesienia (eng. ReferenceError), które zatrzymują działanie skryptu i są momentami bardzo uciążliwe do wykrycia. Dzięki statycznemu typowaniu, jesteśmy w stanie wykrywać je na etapie pisania kodu.
TypeScript na przestrzeni ostatnich lat zyskuje ogromną popularność w społeczności programistów JavaScript i coraz częściej jest nieodłącznym elementem ofert o pracę. W przypadku firm nastawionych na rozwój rozbudowanych aplikacji JavaScript już teraz jest w zasadzie standardem. Biorąc pod uwagę fakt, że najnowsze frameworki (np. Nest.js) wykorzystują TypeScript domyślnie, nauka tej technologii ma ogromny sens w kontekście rozwoju jako programista. I ostatnim argumentem za tym aby wziąć TypeScript na poważnie jest to, że stoi za nim firma Microsoft a on sam rozwijany jest już niemal 10 lat.
Ten kurs został stworzony z myślą o programistach, którzy podstawy TypeScriptu mają już za sobą i chcą poznać jego zaawansowane techniki. Aby w pełni wykorzystać wiedzę z tego kursu, niezbędna jest również zaawansowana znajomość JavaScriptu a w szczególności jego elementów prowadzonych w wersji ES6+. Zdecydowanie polecamy przerobienie kursu Podstawowego TypeScript, który znajdziesz na eduweb, przed korzystaniem z tego materiału.
3.9+
W tej lekcji pokażę ci w jaki sposób możesz tworzyć własne pliki zawierające
definicje typów takie pliki posiadają rozszerzenie dts czyli
definition typescript file i mogą być zarówno wykorzystywane w sytuacji
gdy tworzymy własne moduły które chcemy udostępniać innym bądź korzystać
z nich sami albo w sytuacji gdy pracujemy na istniejących plikach
zawierających definicje typów i chcemy je w jakiś sposób rozszerzyć
to wszystko pokażę ci najlepiej na prostym przykładzie mamy
tutaj przykład z poprzedniej lekcji jednak różnica polega na tym że jak widzisz
mamy tutaj błąd informujący nas o tym że typescript nie odnalazł pliku
zawierającego definicji typów co ciekawe jednocześnie też sugeruje
nam co możemy z tym zrobić czyli po prostu uruchomić polecenie npm install types / ramda
no i oczywiście to rozwiązałoby nasz problem
natomiast ja chciałbym ci pokazać w jaki sposób możesz tworzyć własne
pliki z definicjami typów takie pliki możemy umieścić w katalogu
typings bądź na przykład types w katalogu naszego projektu w tej
sytuacji będą to pliki ramdy więc tworzę tutaj również podkatalog
ramda wewnątrz tego podkatalogu tworzę kolejny plik o
nazwie ramda.d.ts jak widzisz mój edytor rozpoznał
że jest to plik typescript jednak jego ikonka różni się od klasycznego pliku
typescript ze względu na to aby poinformować nas o tym że tutaj przechowujemy
definicje czyli inaczej mówiąc tutaj zapisujemy wyłącznie
kod typescript aby utworzyć teraz definicję typów dla naszego
modułu o nazwie ramda potrzebujemy zadeklarować w następujący
sposób moduł jego nazwa musi pokrywać się z oryginalną
nazwą modułu a następnie wewnątrz nawiasów klamrowych eksportujemy
poszczególne funkcje tak aby typescript miał do nich dostęp no i
tutaj mamy naszą funkcję add i typujemy ją dokładnie tak jak robiliśmy
to wcześniej natomiast różnica jest taka że tutaj skupiamy się wyłącznie na
typowaniu a nie przechowujemy w niej implementacji zatem
jeżeli teraz zakomentuję tą linię i wrócę teraz do naszego głównego pliku
no to zwróć uwagę że typescript odnalazł już plik zawierający definicję
typów dla ramdy i jest to konkretnie ten plik który utworzyliśmy
w tym miejscu ale jednocześnie to zaowocowało kolejnym błędem informującym
nas o tym że metoda add nie istnieje w pliku definicji typu dlatego
też typescript nie jest w stanie nam tutaj w żaden sposób pomagać ale
już w momencie gdy odkomentuję tą linię od razu mamy informację
że błąd z tego pliku zniknął no i faktycznie wszystko działa mało
tego zyskałem tutaj wszystkie korzyści wynikające z posiadania typów czyli
mam tutaj informacje o tym jak wygląda ta funkcja oraz również visual
studio code podpowiada mi składnię czyli zasadniczo już teraz wiesz
w jaki sposób tworzyć pliki zawierające definicję typów dla twoich pakietów
natomiast powiedziałem ci również o tym że możesz rozszerzać
istniejące pakiety czyli wyobraź sobie tutaj sytuację polegającą
na tym że chcesz w jakiś sposób rozszerzyć definicję typów które
są dostępne bezpośrednio w pakiecie zainstalowanym przez ramdę zatem proponuję
abyśmy zainstalowali teraz ten pakiet i zobaczyli co
się stanie patrząc na to na pierwszy rzut oka nic
się nie zmieniło dalej posiadam tutaj podpowiadanie składni oraz pełne informacje o funkcji
add natomiast problem tutaj polega na tym że sama ramda
udostępnia nam zdecydowanie więcej metod do których w tej chwili nie mamy dostępu
wynika to z faktu że zainstalowany przez nas moduł który w
tej chwili trafił do katalogu node modules do podkatalogu types
nie został wczytany ze względu na to że zdefiniowaliśmy ten moduł w tym
miejscu czyli jeżeli teraz zakomentuję ten kod nagle okazuje
się że został wczytany ten oryginalny moduł i mamy dostęp do wszystkich
metod oferowanych przez ramdę przy czym wynika to teraz z faktu że
zadeklarowane przez nas definicje nie istnieją no to pytanie co
teraz mógłbym zrobić aby wykorzystać również definicje które pochodzą stąd
okazuje się że sprawa jest stosunkowo prosta potrzebuję
zaimportować ramdy do naszego pliku oraz w pliku konfiguracyjnym typescriptu
ustawić następującą opcję będzie to opcja
typeRoots zawierająca ścieżki które typescript ma przeszukiwać w celu odnalezienia
plików zawierających definicję typów no więc w naszym przypadku będzie
to katalog node modules / types oraz nowo utworzony katalog
types teraz po zapisaniu tego pliku teoretycznie nic się nie
stało ale tak naprawdę metoda add otrzymała tutaj dodatkowe przeciążenie
aby ci to udowodnić ponownie w pliku zawierającym definicję
zakomentuję teraz ten eksport i teraz mamy jasny dowód tego że
faktycznie ten dodatkowy plik zostaje tutaj uwzględniany w tym
konkretnym przypadku oczywiście nie ma to jakiegoś dużego znaczenia ale tak jak
powiedziałem w niektórych sytuacjach okazuje się to być szczególnie przydatne chciałem
żebyś wiedział że taka możliwość istnieje jednocześnie też w zdecydowanej
większości przypadków będziemy wykorzystywać definicje typów dostępnych na
stronie definitely typed org o której mówiłem w poprzedniej lekcji tak
czy inaczej jest jeszcze jedna rzecz którą chciałbym ci pokazać mianowicie
jeżeli teraz w pliku konfiguracyjnym dodam następującą opcję
ustawioną na true oraz dodatkową opcję lib która w
tym konkretnym przypadku wymagana jest wyłącznie przez dodatkowe funkcje ramdy
no to jeżeli teraz skompiluję nasz projekt za chwilę
w katalogu dist pojawi się nie tylko plik app.js ale
również plik zawierający definicję typów w tej chwili zawiera on oczywiście
jeden prosty eksport ale wystarczy że w pliku app.ts na przykład eksportuję
jakąś funkcję a następnie znowu skompiluję nasz projekt to
w tym momencie definicje typów faktycznie zostały dodane i
na tym etapie na temat tworzenia oraz generowania plików zawierających
definicje typów wiesz w zasadzie wszystko to czego potrzebujesz
teraz dziękuję ci za uwagę i zapraszam cię do obejrzenia kolejnej lekcji