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+
Na tym etapie wiemy już w jaki sposób działa słowo kluczowe this i jak zachowuje się
w różnych sytuacjach oraz jak możemy sobie z tym radzić.
Jednak w tej lekcji chciałbym pokazać Ci jak możemy dodawać typy do słowa
kluczowego this, ponieważ nie jest to do końca oczywiste.
Na potrzeby przykładu utworzę tutaj
obiekt zawierający właściwość oraz metodę.
Metoda ta będzie zwracać nową funkcję a z
kolei ta funkcja informację o naszej właściwości.
Teoretycznie wszystko powinno być w porządku.
W związku z tym że metoda introduce
zwraca nam nową funkcję przypisuję ją to zmiennej a następnie wywołuję.
No i okazuje się, że mamy błąd ale na tym
etapie wiemy już doskonale z czego ten błąd wynika.
Chodzi tutaj konkretnie o fakt że słowo
kluczowe this w tym miejscu wskazuje faktycznie na nasz obiekt user.
Ale już wewnątrz tej funkcji wskazuje na undefined.
Dlatego w momencie gdy odwołujemy się do
właściwości name undefined otrzymujemy jasny komunikat o błędzie.
W poprzedniej lekcji mówiłem Ci, że z takim
błędem możemy sobie poradzić korzystając na przykład z arrow function.
Dzięki temu nie gubimy tutaj kontekstu.
No i wszystko działa poprawnie.
Dodam jeszcze że całkiem popularną praktyką szczególnie w czasach gdy nie
mieliśmy jeszcze dostępu do arrow function było przypisanie this do jakiejś zmiennej np.
self.
Dzięki temu w danej funkcji mogliśmy się do niego odwołać.
I znowu wszystko działało poprawnie.
TypeScript jednak w takiej sytuacji informuje nas o błędzie mówiąc, że dodawanie aliasów
do słowa kluczowego this nie jest tutaj wskazane.
No i faktycznie ja się z nim zgadzam w
związku z tym wracamy do rozwiązania z wykorzystaniem arrow function.
Na tym etapie wszystko wydaje się być w porządku ale nie do końca tak jest w
momencie gdy najedziemy na słowo kluczowe this, okazuje się że jest ono typu any.
A jak wiesz typu any raczej chcemy unikać w TypeScripcie, w związku z tym musimy coś z tym zrobić.
Mało tego w tej chwili TypeScript w żaden
sposób nie informuje nas o tym że istnieje tutaj jakiś problem a dzieje się to z
takiego powodu że w naszym pliku konfiguracyjnym wyłączyłem tryb strict.
W momencie gdy go włączy i wrócę do naszego pliku.
Okazuje się że nic się nie stało, ale tak naprawdę to tylko pozory.
W momencie gdy najadę kursorem na słowo
kluczowe this, nagle okazuje się że w tym momencie TypeScript już nie wskazuje typu
any yylko rzeczywiście wskazuje na nasz obiekt.
Ta sytuacja wyglądałaby inaczej w momencie gdybyśmy nie mieli tutaj arrow function.
W tym momencie TypeScript informuje nas o błędzie mówiącym o tym że słowo kluczowe this
posiada typ any. A wynika to z faktu że TypeScript na tym etapie nie jest w stanie
samodzielnie domyślić się no właśnie jakiego typu jest this.
Przywróćmy więc teraz tutaj funkcję strzałkową aby ponownie uzyskać poprawne typowanie słowa
kluczowego this bo teraz chciałbym pokazać Ci coś jeszcze.
Załóżmy teraz że nasz obiekt user będzie posiadał typ, który zdefiniujemy w
interfejsie. Czyli musimy teraz określić typ właściwości name.
I będzie to String oraz typ właściwości introduce.
Tak właściwie jest to metoda która zwraca nową funkcję.
Zatem na tym etapie możemy po prostu przypisać tutaj typ user.
I teraz okazuje się że TypeScript
ponownie poprawnie określił typ naszego słowa kluczowego this.
No ale w tym momencie nie chciałbym abyś mnie źle zrozumiał typowanie słowa kluczowego this w TypeScripcie
nie sprowadza się wyłącznie do przestawienia opcji w pliku konfiguracji.
Są sytuacje w których
TypeScript nie jest w stanie samodzielnie określić typu słowa kluczowego this.
I wtedy musimy mu w tym pomóc.
Zobaczmy teraz jak to wygląda na drugim przykładzie.
Załóżmy teraz że w naszej aplikacji
pojawia się jakiś link i chcemy zareagować na jego kliknięcie.
W związku z tym tworzę funkcję która będzie blokować domyślne zachowanie tego
przycisku a następnie w konsol logu wyświetlać atrybut href.
Jak widzisz od razu mamy tutaj dwa błędy informujące nas o tym że zarówno argument
event jak i słowo kluczowe this posiadają typ any.
Musimy teraz o to samodzielnie zadbać.
Jeżeli chodzi o argument event nie ma
tutaj filozofii ponieważ jest to właśnie event.
Teraz jednak pytanie brzmi w jaki sposób
możemy zadbać o to aby this również posiadało swój typ.
No i akurat możemy zająć się w taki sposób
że w tym miejscu jako pierwszy parametr określamy właśnie słowo kluczowe this.
Dzięki temu na tym etapie możemy określić jego typ.
I tutaj mamy do dyspozycji kilka różnych
opcji w tym przypadku wiemy że jest to link.
Zatem mamy tutaj do dyspozycji HTMLAnchorElement.
No i na tym etapie wszystko zaczyna być tutaj w porządku.
TypeScript nie tylko przestał nam wyświetlać błędy ale w momencie gdy odwołujemy się do
właściwości this od razu mamy podpowiedzi charakterystyczne właśnie dla elementu anchor.
I w ten sposób wygląda właśnie typowanie this.
Po prostu chcąc dodać do niego typ
umieszczamy go jako pierwszy parametr funkcji wewnątrz którego chcemy
ten typ dodać. I właśnie do tego to wszystko się sprowadza.
Warto też dodać że takie typowanie nie ma
żadnego wpływu na argumenty które przekazujemy do tej funkcji.
Jak widzisz normalnie w tego typu funkcji.
Pierwszym argumentem jest oczywiście event.
Natomiast pomimo tego że umieściliśmy
tutaj słowo kluczowe this dalej mamy do niego dostęp i wszystko jest w porządku.
Podsumowując typowanie słowa kluczowego this mówimy tutaj o dwóch sytuacjach.
Pierwszą z nich jest moment w którym TypeScript automatycznie określa jego typ na
podstawie samego kontekstu i często jest to dokładnie to o co nam chodzi.
A w momencie gdy sobie z tym nie radzi mamy możliwość określenia samodzielnie
typu słowa kluczowego this przekazując je jako pierwszy parametr w naszej funkcji.
W tym wszystkim najważniejsze jest jednak to aby słowo kluczowe this nie posiadało
typu any. I przedtem akurat możemy się ochronić włączając opcję strict w pliku
konfiguracji TypeScriptu lub jeżeli z jakiegoś powodu nie chcemy korzystać z tej opcji.
Mamy do dyspozycji jeszcze flagę noImplicitAny
którą również możemy ustawić na true. Po prostu chodzi o to że ta opcja jest
uwzględniona automatycznie w tej. Razem zresztą z kilkoma innymi opcjami które
również możesz włączać i wyłączać indywidualnie. Na ten moment dziękuję Ci za
uwagę i słyszymy się za chwilę w kolejnej lekcji.
user interfac · 3 min
interface User {
name: string,
introduce: () => Function
}user object · 1 min
// custom
function customThis() {
return this
}
const obj = { x: 1 }
const bounded = customThis.bind(obj)
bounded() /*?*/
customThis.call(obj) /*?*/
customThis.apply(obj, []) /*?*/