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 chwili przechodzimy już do podsumowania naszego kursu
i w ramach niego chciałbym podzielić się z tobą pewnymi wskazówkami które pozwolą
ci wykorzystać tą wiedzę którą zdobyłeś na przestrzeni tego i poprzedniego
kursu no i wykorzystać ją w praktyce bez wątpienia takim tematem
jest migracja do typescriptu istniejącego projektu javascript na
początku kursu wspominałem że kod javascript jest w pełni kompatybilny
z kodem typescript i choć teoretycznie jest to prawda to w momencie
gdy do istniejącego projektu javascript podłączamy typescript wymaga
on od nas dodatkowej konfiguracji no i jednocześnie zadbania o to
aby stopniowo przepisywać kod javascript na typescript istnieje
ku temu kilka strategii które za chwilę ci omówię ale gdybym miał
jest sprowadzić do kilku zdań powiedziałbym tak migrację należy
rozpocząć od podłączenia typescriptu do naszego projektu a następnie
doprowadzenia do tego aby w ogóle go uruchomić w momencie gdy to już
zrobimy połowa pracy jest za nami ponieważ potem wystarczy że stopniowo
będziemy przepisywać istniejący kod na typescript no i z biegiem
czasu cała nasza aplikacja zostanie przepisana do tego języka ostatecznie
z całą pewnością musimy przygotować się na to że nie wszystko pójdzie od razu zgodnie
z naszym planem mało tego mogą zdarzyć się sytuacje chociażby
w momencie gdy mamy rozbudowany projekt że migracja do typescriptu musi
stać się pewnego rodzaju priorytetem aby w ogóle doszła do skutku dzięki
temu że taki prioryted sobie nadamy sam proces migracji potrwa
po prostu krócej i tak naprawdę w ogóle się wydarzy no
bo jeżeli ciągle będziemy traktować to jako dodatek i nieustannie nawet tworząc
nowe funkcje będziemy omijać dodawanie typowania no to donikąd
nas to nie doprowadzi kontynuując jednak temat strategii pierwszą
z nich jest miksowanie kodu javascript z kodem typescript wygląda
to tak że do naszego projektu po prostu dodajemy pliki typescript a w pliku
tsconfig.json ustawiamy opcję allowJs ustawioną na true
w ten sposób zwróć uwagę że mam w moim projekcie plik app.js
ale w momencie gdy uruchomię proces kompilacji typescriptu no
to pomimo tego że nie mam tutaj kodu typescript i nie mam również informacji
o typach nie wystąpił tutaj żaden błąd a plik app.js po prostu został
przeniesiony do katalogu dist i w tym momencie dopiero gdybym dodał
tutaj jakiś plik typescript to on oczywiście zostałby zweryfikowany
pod kątem typów z jednej strony od razu podczas developmentu mamy informacje
o błędach no a jednocześnie w procesie kompilacji plik app.js
zostanie tutaj zignorowany natomiast typescript zostanie zweryfikowany
pod kątem istniejących błędów no i co prawda w tym momencie mamy
tutaj tylko dwa pliki natomiast na przestrzeni nieco większego projektu sprawdza się
to dość dobrze podkreślam tylko jedną rzecz abyś dbał o to aby
przy rozbudowie plików app.js regularnie dodawać typy w
momencie gdy nie będziesz tego robił zawsze na koniec dnia będziesz zostawał z taką
hybrydą kodu javascript oraz typescript tymczasem przejdźmy do
kolejnej strategii i ona akurat mówi o wykorzystaniu JSDoc
czyli generalnie dodawania typów poprzez wykorzystanie komentarzy
bezpośrednio w pliku javascript i w praktyce wygląda to tak że mamy
zestaw adnotacji które możemy wykorzystywać w komentarzach do
tego aby opisywać poszczególne typy zmiennych oraz funkcji na
podstawie tak opisanego kodu javascript jesteśmy w stanie wygenerować pliki
definicji typów które pokazywałem ci w jednej z poprzednich lekcji
tymczasem link do tej strony dołączam do materiałów tej lekcji i jednocześnie
wracam do kolejnej strategii a tą strategią jest inkrementacja została
na świetnie opisana w tym artykule który na przykładzie aplikacji zawierającej ponad
100000 linii kodu opisuje proces takiej migracji gorąco
zachęcam cię do spokojnego zapoznania się z nim a tymczasem zobaczmy szybko
co oni tutaj właściwie zrobili tutaj pierwszym krokiem jaki podjął zespół programistów
pracujący nad tym projektem było to aby utworzyć plik tsconfig
a następnie zmienić rozszerzenia plików z js na ts
efekt tego był taki że otrzymali komunikat o tym że w projekt znajduje się
ponad 3000 błędów jak się pewnie domyślasz naprawienie ich wszystkich za
jednym razem nie było możliwe w związku z tym skonfigurowali narzędzie do testu
w taki sposób aby za każdym razem uruchamiało projekt z pomocą kompilera
typescript a następnie zapisywało snapshot zawierający
informacje o liście błędów typescript które aktualnie występują w
projekcie no i cały sekret tutaj polegał na tym że w momencie gdy
programiści dodawali jakieś zmiany snapshot ten był regenerowany a
następnie uwzględniany w procesie pull request w momencie gdy jakaś wprowadzana
zmiana generowała więcej błędów typescript niż faktycznie ich poprawiała
nie była akceptowana zatem celem było tutaj stopniowe zmniejszanie
liczby błędów oczywiście w ramach bieżącej konfiguracji typescriptu
w momencie gdy te błędy zostawały zmniejszane stopniowo zwiększono
też wymagania pliku konfiguracyjnego typescript względem kodu dzięki
temu w wyniku samego rozwoju takiej aplikacji który trwał tutaj nieprzerwanie
z biegiem czasu proces migracji tutaj postępował raz
jeszcze bardzo zachęcam cię do zapoznania się z tym artykułem oraz repozytorium
które możesz pobrać tutaj który pokazuje w jaki sposób można
skonfigurować takie snapshoty tymczasem skoro przeszliśmy już przez takie
trzy ogólne strategie migracji istniejącego kodu javascript do typescript
spróbujmy również zmigrować nasz projekt jak widzisz mam tutaj
naprawdę prostą aplikację express.js czyli kod napisany w node.js
który bardzo chciałbym zmigrować do typescriptu pierwszy
krok tak naprawdę mam już za sobą ponieważ chodziło tutaj o utworzenie pliku konfiguracyjnego
typescript tutaj jak widzisz mam takie podstawowe ustawienia oraz tą
opcję allowJs którą w tym momencie chciałbym wyłączyć teraz jeżeli
chciałbym skompilować ten projekt zobacz co się stanie otrzymałem
informację o błędzie który zawiera się w pliku module.ts no i faktycznie
ten błąd istnieje więc na razie go zlikwiduję ale jeżeli teraz
ponownie uruchomię nasz kompilator wszystko teoretycznie jest w porządku ale
mi również zależy na tym aby nasz plik główny aplikacji został interpretowany
jako typescript zatem zmieniam rozszerzenie tego pliku i ponownie
uruchamiam proces kompilacji no i teraz nagle się okazuje
że jednak brakuje mi różnych typów w kodzie który mam zapisany
tutaj i konkretnie są to trzy błędy dotyczą one tego że
mam tutaj niejawnie określony typ any parametrów funkcji w
tej sytuacji mógłbym z jednej strony dodać tutaj po prostu wprost typ any
albo alternatywnie wyłączyć tryb strict w pliku konfiguracyjnym typescript
jeżeli teraz uruchomię proces kompilacji mam
jeszcze jeden błąd informujący mnie o tym że nie mamy tutaj definicji typów zarówno
dla node.js jak i express w związku z tym dodam teraz te typy
no i teraz ponownie uruchomię kompilator w tym momencie
żadnych błędów już tutaj nie mamy no i nasz projekt został poprawnie
wygenerowany i swoją drogą chciałbym wrócić teraz jeszcze do jednej
małej rzeczy mianowicie w związku z tym że zainstalowaliśmy tutaj definicję
typów dla express oraz node.js no to możemy wykorzystać
je w naszym projekcie podobnie zresztą musimy zrobić z każdą biblioteką
którą importujemy do naszego projektu jednocześnie skoro posiadamy
już informacje o typach morzem je również wykorzystać jeżeli
w tym momencie przestawił bym tryb strict na true no to jak pamiętasz
kompilator wyrzuci nam teraz błędy spróbujemy je teraz naprawić
w tym konkretnym momencie mamy tutaj informacje o tym że parametry
naszej funkcji nie posiadają odpowiedniego typu zatem skoro korzystamy
już z kompilatora typescript możemy tutaj wykorzystać importy es6
czyli z pomocą słowa kluczowego import importuję express oraz
niezbędne typy które posłużą mi do tego aby określić typy tych dwóch zmiennych
i w tym momencie zamieniliśmy kod javascript na typescript jednocześnie też
chciałbym tutaj zwrócić uwagę na jedną rzecz o której w tym momencie z jakiegoś powodu
mój kompilator nie informuje o właśnie w tej chwili przypomniało mu się
o błędzie jak widzisz otrzymaliśmy tutaj informację mówiącą
nam o tym że w ten sposób nie możemy zaimportować obiektu exspress ponieważ
został on wyeksportowany w sposób wspierany przez CommonJS modules
zatem to co możemy z tym zrobić to po prostu posłuchać sugestii
którą mamy dokładnie tutaj czyli w pliku konfiguracyjnym dodajemy
następującą flagę no i teraz jeżeli damy chwilę naszemu kompilatorowi
no to wszystko powinno być w porzadku i teraz tylko zapiszę
plik a następnie uruchomię ponownie kompilator i nasz projekt powinien
działać tak jak należy faktycznie żadnych błędów tutaj nie mamy kod
został tutaj wyeksportowany tak jak chcemy i wszystko wydaje się
działać ostatecznie to co może cię jeszcze tutaj interesować to
po prostu uruchomienie tego projektu jeżeli teraz uruchomię plik
z poleceniem node otrzymam szereg różnych błędów to co
jednak możemy z tym zrobić to uruchomić projekt z poleceniem ts-node
jak widzisz wykorzystuję tutaj npx oczywiście sam ts-node możesz zainstalować
globalnie w swoim systemie w każdym razie w momencie gdy uruchamię
teraz ten projekt otrzymuję informację o tym że serwer nie
może zostać uruchomiony bo mam uruchomiony jakiś inny serwer teraz wykorzystując
magia kina już to naprawiłem i spróbujemy uruchomić go ponownie teraz
wszystko wydaje się działać poprawnie a ja po wejściu na adres localhost 3000
mam taki oto komunikat ale domyślam się że w procesie developmentu
interesowałoby cię to że jeżeli wprowadzisz jakąś zmianę do pliku to fajnie
by było aby te zmiany zostały natychmiast odzwierciedlane w przeglądarce w
tej chwili musielibyśmy ponownie uruchomić serwer rozwiązanie które
może ci przyjść do głowy to po prostu wykorzystanie narzędzia nodemon i problem
polega na tym że niestety nodemon również z typescriptem nie działa aczkolwiek
jest możliwość uruchomienia ts-node oraz nodemon ale w tym wszystkim
mamy jeszcze jedną alternatywę tą alternatywą jest
ts-node-dev jeżeli teraz uruchomię ten serwer w taki sposób
to otrzymuję błąd informujący mnie o tym że nie mam zainstalowanego typescriptu
no i faktycznie jest to prawda w tym momencie zainstalowałem
lokalnie w moim projekcie typescript i jeżeli teraz ponownie uruchomię to polecenie wygląda
na to że serwer został uruchomiony i faktycznie wszystko tutaj działa
jeżeli teraz wprowadzę jakąś zmianę do pliku a następnie zapiszę
ten plik to od razu mamy informacje o tym że serwer został zrestartowany
i rzeczywiście zmiany są widoczne tak że jak widzisz
w tym momencie przeszliśmy taki proces migracji kodu javascript do kodu
typescript na przykładzie aplikacji express mam nadzieję że to wszystko
dało ci taki ogólny zarys tego w jaki sposób wygląda migracja projektów
javascript do typescript no i jednocześnie muszę podkreślić że sam proces
migracji u podstaw jest dokładnie taki sam wszędzie ale znacząco
się różni w zależności od specyfiki aplikacji jej rozmiaru oraz naszych
wymagań proponuję więc teraz abyś po prostu sprawdził jak to wygląda
na jednym z twoich projektów i tutaj raz jeszcze musisz pamiętać o tym
że w pierwszej kolejności tworzysz plik tsconfig.json z jakimiś ustawieniami
które pasują do twoich potrzeb a następnie zamieniasz rozszerzenia plików
javascript na typescript w momencie uruchomienia projektu od razu będziesz
miał informacje o ewentualnych błędach które musisz poprawić raz
jeszcze podkreślam że najważniejsze jest tutaj doświadczenie i po prostu nastawienie się
na to że tych błędów na początkowym etapie będzie dużo ale tak
jak mówię dobra wiadomość jest taka że stopniowo możemy sobie z nimi bez problemu
radzić tymczasem ja dziękuję ci za uwagę i słyszymy się za chwilę
w kolejnej lekcji