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+
Kolejnym typem o którym chciałbym trochę więcej powiedzieć w tym kursie jest
typ enum podobnie jak o obiektach o nim również rozmawialiśmy w kursie
podstawowym natomiast teraz chciałbym przedstawić ci go nieco z innej perspektywy
sam sposób definiowania typu enum już znasz z poprzedniego kursu
natomiast teraz spójrzmy na to nieco inaczej mianowicie
nie wiem czy zdajesz sobie z tego sprawę ale w javascripcie istnieje tylko jeden
typ który posiada skończoną liczbę wartości jest to typ logiczny
zawierający wyłącznie prawdę lub fałsz typ enum można postrzegać
jako taki dodatkowy typ który umożliwia definiowanie skończonych
zestawów wartości przykładowo tutaj mamy typ określający
dostępność i jego poszczególne wartości ustawione są na dni tygodnia na
tym etapie wiemy również że do każdej z tych wartości przyporządkowana jest liczba
począwszy od zera i jeżeli mamy taką potrzebę moglibyśmy nadpisać
domyślną wartość poprzez inicjalizowanie nowej i na tym etapie typescript
zadba o to aby kolejne wartości były implementowane właśnie począwszy
od tej zdefiniowanej tutaj to co jednak jest najciekawsze w przypadku
typu enum to sposób w jaki ten typ jest kompilowany do javascriptu
jeżeli teraz wykonam polecenie tsc app.ts zostanie
dla nas wygenerowany plik javascript który jak widzisz posiada dość
ciekawą strukturę mamy tutaj zdefiniowaną nową zmienną do której
w tym miejscu przypisywany jest pusty obiekt następnie mamy
tutaj do czynienia z dość ciekawym przypisaniem wartości polegający na tym
że w tym miejscu określamy klucz poszczególnej właściwości i w tym
przypadku są to liczby a następnie przypisujemy do nich wartość tekstową
taki zapis daje nam szczególne możliwości które określamy
mianem odwróconego mapowania czy też reverse mapping najlepiej
będzie jak pokażę ci to na przykładzie wiemy już że do poszczególnych wartości
możemy odwołać się po ich nazwie i tutaj w takiej sytuacji otrzymujemy
ich wartość liczbowa nic nie stoi jednak na przeszkodzie abyśmy w tej
sytuacji odwołali się również do wartości liczbowej w tym
momencie wartość którą tutaj otrzymamy będzie ustawiona na nazwę tej
właściwości dzięki temu jak widzisz możemy tutaj odczytywać
wartości na 2 różne sposoby co daje nam dość ciekawe możliwości mało
tego nic też nie stoi na przeszkodzie abyśmy odwołali się do właściwości w następujący
sposób dzięki temu otrzymamy tutaj ponownie wartość liczbową
aczkolwiek jak widzisz eslint podkreśla mi że w tej sytuacji po
prostu taki zapis służy do tego aby wykorzystywać w tym miejscu zmienne
więc jeżeli zapiszemy ten klucz w zmiennej key będziemy w stanie
go przekazać i wszystko będzie tutaj w porządku gdyby
tego było mało to w tym miejscu możemy stosować również niektóre wyrarzenia na
przykład możemy odczytać długość ciągu znaków dzięki czemu otrzymamy
tutaj wartość liczbową która zostanie przypisana do właściwości wednesday
natomiast zwróć uwagę że w tym momencie typescript oczekuje od nas tego
abyśmy tutaj również dosłownie zainicjalizowany wartość dzięki
temu na tej podstawie będzie w stanie określić wartość kolejnej właściwosci to
akurat pokazuje nam jeszcze jedną możliwość związaną z typem enum a
konkretnie chodzi mi tutaj o fakt że w przypadku tego typu możemy również
przypisywać wartości tekstowe czyli jeżeli zdefiniuję
tutaj nowy typ wewnątrz którego jak sama nazwa wskazuje będę przechowywał informacje
o rozszerzeniu no to w takiej sytuacji zyskuję pewne możliwości a
niektóre tracę otóż chodzi tutaj o fakt że w tym momencie gdy odwołuję
się do nazwy właściwości otrzymuję wartość liczbową która tak naprawdę niewiele
mi mówi natomiast już w tym drugim przypadku sytuacja wygląda nieco inaczej
jeżeli teraz odwołam się po nazwie właściwości otrzymam
wartość tekstową która dokładnie określa mi to z czym mam tutaj do czynienia
ostatecznie też jeżeli mielibyśmy ku temu dobry powód moglibyśmy
połączyć wartości liczbowe z tekstowym i tutaj sytuacja wyglądałaby
tak że typescript na tym etapie jest w stanie samodzielnie określić wartości
ale później tą umiejętność już traci i ta umiejętność jest
niedostępna do momentu w którym ponownie zainicjalizujemy kolejną wartość
i jak widzisz tutaj mamy ponownie wartość 6 oczywiście
taki przykład jest ciekawostką którą warto znać natomiast mi osobiście
nie przychodzi jakiś sensowny pomysł praktycznego wykorzystania teraz
biorąc pod uwagę zarówno jeden sposób definiowania typu enum jak i drugi
czyli ten wykorzystujący liczby bądź wartości tekstowe zdecydowanie
lepiej jest wykorzystywać wartości tekstowe nie tylko z tego powodu że
podczas logowania czy wyświetlania informacji otrzymujemy tutaj bardziej sensowną
informację ale również z bardziej konkretnego powodu otóż
jeżeli zdefiniujemy sobie tutaj funkcję której argument jest typu enum
który posiada wartości numeryczne to typescript nie będzie miał problemu jeżeli przekażemy
tutaj dowolną wartość liczbową taka sytuacja naturalnie nie jest
czymś czego byśmy oczekiwali w związku z tym zdecydowanie lepiej jest
preferować typ enum posiadający wartości tekstowe tutaj
taka sytuacja po prostu nie występuje tutaj taka sytuacja
nie występuje ale jednocześnie musimy bardziej się postarać przekazując
wartości do tej funkcji to co jeszcze na tym etapie chciałbym ci pokazać
to że jeżeli usuniemy sobie tutaj ten kod a następnie zamienimy nasz
enum na const enum to jeżeli teraz skompilujemy sobie ten kod otrzymamy
nieco inny rezultat niż poprzednim razem nagle okazuje
się że mamy tutaj wyłącznie wartość 0 a definicja naszego
obiektu przechowującego wartości w typie enum całkowicie zniknęła
raczej mówiąc definicja typu enum na etapie kompilacji została
tutaj usunięta a poszczególne wartości zostały po prostu podmienione
wartościami liczbowymi i jest to z pewnością coś czego warto być świadomym
przywrócę teraz poprzedni kod i szybko powiem
ci jeszcze o tym w jakich sytuacjach typ enum sprawdza się idealnie taką
sytuacją może byś chociaż bym moment w którym pracujemy z kilkoma stałymi
czyli generalnie wartościami które nie ulegają zmianie na etapie wykonywania
programu więc dobrze jest je pogrupować żeby na przykład w tym miejscu
nie zrobić jakiejś literowki poza tym gdyby takich rozszerzeń było nieco więcej
mielibyśmy po prostu problem z ich zapamiętaniem bardzo dobrym
przykładem są tutaj chociażby przechowywanie poszczególnych uprawnień konkretnych
grup użytkowników bądź na przykład kody numeryczne klawiszy ostatecznie
też typy enum świetnie sprawdzają się w przypadku gdy pracujemy z zestawem konkretnych
ciągów znaków chociażby określenia typów są dobrym przykładem natomiast
bez wątpienia takich przykładów jest więcej na tym etapie myślę że
wiesz już wystarczająco dużo na temat typu enum i mam nadzieję
że po obejrzeniu tej lekcji przekonałeś się do niego jeszcze bardziej teraz
nie pozostaje mi nic innego jak po prostu zaprosić cię do kolejnej lekcji
Availability · 1 min
enum Availability {
Monday,
Tuesday,
Wednesday = '123'.length,
Thursday = 4,
Friday,
}Keys · 3 min
const key = 'Monday';
Availability.Monday /*?*/
Availability[key] /*?*/
Availability[5] /*?*/FileTypes · 4 min
enum SupportedFileTypes {
png = 'image/png',
jpg = 'image/jpeg',
}
SupportedFileTypes.png /*?*/Enum · 6 min
function foo(bar: SupportedFileTypes) {}
foo(SupportedFileTypes.png)