Facebook - konwersja
Czytaj fragment
Pobierz fragment

Programowanie w TypeScript - ebook

Data wydania:
1 stycznia 2020
Format ebooka:
EPUB
Format EPUB
czytaj
na czytniku
czytaj
na tablecie
czytaj
na smartfonie
Jeden z najpopularniejszych formatów e-booków na świecie. Niezwykle wygodny i przyjazny czytelnikom - w przeciwieństwie do formatu PDF umożliwia skalowanie czcionki, dzięki czemu możliwe jest dopasowanie jej wielkości do kroju i rozmiarów ekranu. Więcej informacji znajdziesz w dziale Pomoc.
Multiformat
E-booki w Virtualo.pl dostępne są w opcji multiformatu. Oznacza to, że po dokonaniu zakupu, e-book pojawi się na Twoim koncie we wszystkich formatach dostępnych aktualnie dla danego tytułu. Informacja o dostępności poszczególnych formatów znajduje się na karcie produktu.
, MOBI
Format MOBI
czytaj
na czytniku
czytaj
na tablecie
czytaj
na smartfonie
Jeden z najczęściej wybieranych formatów wśród czytelników e-booków. Możesz go odczytać na czytniku Kindle oraz na smartfonach i tabletach po zainstalowaniu specjalnej aplikacji. Więcej informacji znajdziesz w dziale Pomoc.
Multiformat
E-booki w Virtualo.pl dostępne są w opcji multiformatu. Oznacza to, że po dokonaniu zakupu, e-book pojawi się na Twoim koncie we wszystkich formatach dostępnych aktualnie dla danego tytułu. Informacja o dostępności poszczególnych formatów znajduje się na karcie produktu.
(2w1)
Multiformat
E-booki sprzedawane w księgarni Virtualo.pl dostępne są w opcji multiformatu - kupujesz treść, nie format. Po dodaniu e-booka do koszyka i dokonaniu płatności, e-book pojawi się na Twoim koncie w Mojej Bibliotece we wszystkich formatach dostępnych aktualnie dla danego tytułu. Informacja o dostępności poszczególnych formatów znajduje się na karcie produktu przy okładce. Uwaga: audiobooki nie są objęte opcją multiformatu.
czytaj
na tablecie
Aby odczytywać e-booki na swoim tablecie musisz zainstalować specjalną aplikację. W zależności od formatu e-booka oraz systemu operacyjnego, który jest zainstalowany na Twoim urządzeniu może to być np. Bluefire dla EPUBa lub aplikacja Kindle dla formatu MOBI.
Informacje na temat zabezpieczenia e-booka znajdziesz na karcie produktu w "Szczegółach na temat e-booka". Więcej informacji znajdziesz w dziale Pomoc.
czytaj
na czytniku
Czytanie na e-czytniku z ekranem e-ink jest bardzo wygodne i nie męczy wzroku. Pliki przystosowane do odczytywania na czytnikach to przede wszystkim EPUB (ten format możesz odczytać m.in. na czytnikach PocketBook) i MOBI (ten fromat możesz odczytać m.in. na czytnikach Kindle).
Informacje na temat zabezpieczenia e-booka znajdziesz na karcie produktu w "Szczegółach na temat e-booka". Więcej informacji znajdziesz w dziale Pomoc.
czytaj
na smartfonie
Aby odczytywać e-booki na swoim smartfonie musisz zainstalować specjalną aplikację. W zależności od formatu e-booka oraz systemu operacyjnego, który jest zainstalowany na Twoim urządzeniu może to być np. iBooks dla EPUBa lub aplikacja Kindle dla formatu MOBI.
Informacje na temat zabezpieczenia e-booka znajdziesz na karcie produktu w "Szczegółach na temat e-booka". Więcej informacji znajdziesz w dziale Pomoc.
Czytaj fragment
Pobierz fragment
84,00

Programowanie w TypeScript - ebook

Każdy programista dynamicznie typowanego języka wie, jak trudno jest skalować go do wielu wierszy kodu. To dlatego w firmach Facebook, Google i Microsoft wymyślono warstwy do stopniowego wprowadzania statycznej kontroli typów w dynamicznie typowanym kodzie JavaScript i Python. Ta praktyczna książka opisuje, co wyróżnia TypeScript na tle innych warstw typów oraz pokazuje, że dzięki zaawansowanemu systemowi typowania statycznego programowanie staje się przyjemnością.
Jeśli jesteś średniozaawansowanym programistą JavaScript, autor Boris Cherny nauczy Cię, jak opanować język TypeScript. Zrozumiesz, w jaki sposób TypeScript pomaga w eliminowaniu błędów i usprawnia współpracę wielu programistów nad tym samym kodem.
W tej książce:
• Zaczniesz od podstaw: Poznasz różne typy i operatory TypeScript, dowiadując się, do czego służą i jak ich używać.
• Poznasz bardziej zaawansowane zagadnienia: Zrozumiesz zaawansowany system typów TypeScript m.in. jak bezpiecznie obsługiwać błędy i budować programy asynchroniczne.
• Zdobędziesz praktyczne umiejętności: Dowiesz się jak, używać języka TypeScript w połączeniu z ulubionymi frameworkami front-end i back-end, migrować istniejący projekt JavaScript do TypeScripta i uruchomić aplikację TypeScript w środowisku produkcyjnym.

Kategoria: Programowanie
Zabezpieczenie: Watermark
Watermark
Watermarkowanie polega na znakowaniu plików wewnątrz treści, dzięki czemu możliwe jest rozpoznanie unikatowej licencji transakcyjnej Użytkownika. E-książki zabezpieczone watermarkiem można odczytywać na wszystkich urządzeniach odtwarzających wybrany format (czytniki, tablety, smartfony). Nie ma również ograniczeń liczby licencji oraz istnieje możliwość swobodnego przenoszenia plików między urządzeniami. Pliki z watermarkiem są kompatybilne z popularnymi programami do odczytywania ebooków, jak np. Calibre oraz aplikacjami na urządzenia mobilne na takie platformy jak iOS oraz Android.
ISBN: 978-83-01-21122-6
Rozmiar pliku: 2,6 MB

FRAGMENT KSIĄŻKI

ROZDZIAŁ 1

Wprowadzenie

Czyli zdecydowałeś się kupić książkę o TypeScripcie. Dlaczego?

Być może masz już dość dziwnych błędów JavaScriptu typu cannot read property coś tam coś tam undefined. A może słyszałeś, że TypeScript podnosi skalowalność kodu i chciałeś sprawdzić, o co tyle szumu? Może jesteś programistą C# i zastanawiasz się, czy nie spróbować całego tego JavaScriptu. A może jesteś programistą języka funkcyjnego i zdecydowałeś, że nadszedł czas wrzucić wyższy bieg. Może twój szef ma już tak dość problemów produkcyjnych powodowanych przez twój kod, że dał ci tę książkę pod choinkę (powiedz stop, gdy będziemy na dobrym tropie).

Niezależnie od osobistych przyczyn, to prawda, co mówią o języku TypeScript – naprawdę znajdzie on zastosowanie w nowej generacji aplikacji sieci Web, aplikacji mobilnych i Internetu rzeczy (Internet of Things – IoT). Zwiększy on bezpieczeństwo programów, będzie pełnił funkcję dokumentacji dla nas i przyszłych programistów, ułatwi przeprowadzanie refaktoryzacji i sprawi, że połowa naszych testów jednostkowych stanie się niepotrzebna („Jakie testy jednostkowe?”). Dzięki TypeScript podwoi się twoja produktywność w pracy, a przy odrobinie szczęścia uda ci się wyciągnąć szczęśliwy los na loterii w prima aprilis.

Ale najpierw pozwól nam wyjaśnić, co mamy na myśli, mówiąc o „bezpieczeństwie”. Oczywiście chodzi nam o bezpieczeństwo typów.

Bezpieczeństwo typów

Wykorzystywanie typów do powstrzymywania programów przed podejmowaniem nieprawidłowych akcji1.

Oto kilka przykładów nieprawidłowych akcji:

- mnożenie liczby i listy,
- wywoływanie funkcji na liście łańcuchów, mimo że tak naprawdę potrzebuje ona listy obiektów,
- wywoływanie metody na obiekcie, który w rzeczywistości nie ma tej metody,
- importowanie modułu, który został usunięty.

Niektóre języki programowania próbują, jak najlepiej potrafią, radzić sobie z tego typu błędami. Próbują domyślić się, do czego miała prowadzić nieprawidłowa akcja, ponieważ każdy robi, co może, prawda? Weźmy pod uwagę następujący kod JavaScriptu:

3 + // Otrzymujemy łańcuch “3”

let obj={}

obj.foo // Otrzymujemy undefined

function a(b) {

return b/2

}

a(“z”) // Otrzymujemy NaN

Jak widać, zamiast zgłaszać wyjątek w odpowiedzi na próbę wykonania nieprawidłowej akcji, JavaScript próbuje zaradzić sytuacji i unikać wyjątków, gdy jest to możliwe. Czy JavaScript chce pomóc? Na pewno. Czy ułatwia szybkie zidentyfikowanie błędów? Raczej nie.

A teraz wyobraźmy sobie, że JavaScript zgłasza więcej wyjątków, zamiast po cichu radzić sobie ze stworzoną przez nas sytuacją. Moglibyśmy otrzymać następujące informacje zwrotne:

3 + // Błąd: Czy naprawdę chcesz dodać liczbę i tablicę?

let obj={}

obj.foo // Błąd: Zapomniałeś zdefiniować w obj właściwość “foo”.

function a(b) {

return b/2

}

a(“z”) // Błąd: Funkcja “a” oczekuje liczby,

// a przekazałeś łańcuch.

Proszę nas źle nie zrozumieć: gotowość do rozwiązywania naszych błędów to kapitalna cecha języka programowania (gdyby było to możliwe nie tylko w przypadku programów). W JavaScript ta funkcja oddala jednak moment popełnienia błędu w kodzie od momentu dowiadywania się o tym, że popełniliśmy błąd w kodzie. A to często oznacza, że o naszym błędzie dowiadujemy się dopiero od innych osób.

W związku z tym pojawia się pytanie, kiedy dokładnie JavaScript informuje nas, że popełniliśmy błąd.

Odpowiedź brzmi: po uruchomieniu programu. Program może zostać uruchomiony, gdy testujemy go w przeglądarce lub gdy użytkownik odwiedzi naszą stronę, lub gdy wykonamy test jednostkowy. Zdyscyplinowani programiści, którzy piszą dużo testów jednostkowych i e2e (end-to-end), wykonują testy dymne przed wypchnięciem kodu i testują go lokalnie przed przekazaniem do użytkowników, zazwyczaj dowiadują się o swoich błędach przed użytkownikami. Ale co z resztą programistów?

Tu z pomocą przychodzi TypeScript. Jego dużą zaletą jest nie tylko dostarczanie pomocnych komunikatów o błędach, lecz także moment ich przekazywania: TypeScript pokazuje komunikaty o błędach w edytorze tekstowym w czasie wpisywania kodu. To oznacza, że nie musimy polegać na tym, że tego typu błędy zostaną wykryte przez testy jednostkowe, testy dymne lub naszych współpracowników: TypeScript wykrywa te błędy i informuje nas o nich podczas pisania programu. Zobaczmy, co TypeScript mówi o naszym poprzednim przykładzie:

3 + // Błąd TS2365: Nie można zastosować operatora ‘+’ do typów ‘3’

// i ‘never’.

let obj = {}

obj.foo // Błąd TS2339: Właściwość ‘foo’ nie istnieje w typie ‘{}’.

function a(b: number) {

return b/2

}

a(“z”) // Błąd TS2345: Nie można przypisać argumentu typu ‘”z”’

// do parametru typu’number’.

Nie tylko eliminuje on całe klasy błędów związanych z typami, ale tak naprawdę zmienia sposób pisania kodu. W efekcie zaczynamy od naszkicowania programu na poziomie typów, a dopiero później wypełniamy go na poziomie wartości2 – przypadki brzegowe bierzemy pod uwagę już w fazie projektowania i tworzymy programy, które są prostsze, szybsze, bardziej zrozumiałe i łatwiejsze w utrzymywaniu.

Gotowy do rozpoczęcia przygody? W takim razie wyruszamy!ROZDZIAŁ 2

TypeScript: obraz ogólny

W kilku kolejnych rozdziałach przedstawimy język TypeScript, wyjaśnimy, w jaki sposób działa kompilator TypeScriptu (w skrócie TSC – TypeScript Compiler) i przedstawimy przegląd funkcji TypeScriptu oraz wzorców, które można przy ich użyciu implementować. Zaczniemy od kompilatora.

Kompilator

W zależności od tego, w jakim języku wcześniej programowałeś (oczywiście zanim zdecydowałeś się kupić tę książkę i już na zawsze pozostać przy bezpieczeństwie typów), możesz w różny sposób postrzegać działanie programów. TypeScript pracuje inaczej niż większość popularnych języków, takich jak JavaScript czy Java, dlatego musimy upewnić się, że dobrze się rozumiemy.

Zacznijmy od podstaw: programy to pliki, które zawierają pewien tekst napisany przez programistę. Ten tekst jest parsowany przez specjalny program nazywany kompilatorem, który przekształca go w drzewo składniowe (abstract syntax tree, AST), czyli strukturę danych, która ignoruje takie elementy, jak: odstępy, komentarze i twoje stanowisko w debacie tabulatory kontra spacje. Następnie kompilator konwertuje to AST do niskopoziomowej reprezentacji nazywanej kodem bajtowym. Ten kod bajtowy można przekazać do innego programu nazywanego środowiskiem uruchomieniowym w celu jego ewaluacji i otrzymania wyniku. A zatem gdy uruchamiamy program, tak naprawdę instruujemy środowisko uruchomieniowe, aby przeprowadziło ewaluację kodu bajtowego wygenerowanego przez kompilator na podstawie AST sparsowanego na bazie naszego kodu źródłowego. Szczegóły mogą się różnić, ale ogólny schemat dotyczy większości języków.

Podsumowując, oto podstawowe kroki:

1. Program jest parsowany do AST.
2. AST jest kompilowane do kodu bajtowego.
3. Środowisko uruchomieniowe przeprowadza ewaluację kodu bajtowego.

TypeScript różni się tym, że zamiast dokonywać kompilacji bezpośrednio do kodu bajtowego, przeprowadza kompilację do... kodu JavaScriptu! Następnie ten kod JavaScriptu można, jak zwykle, wykonać w przeglądarce, przy użyciu NodeJS lub własnoręcznie za pomocą kartki i długopisu (jeśli czytasz to po wybuchu buntu maszyn).

Być może zastanawiasz się: „Moment! W poprzednim rozdziale napisano, że TypeScript zwiększa bezpieczeństwo kodu! Kiedy to zachodzi?”.

Dobre pytanie. Faktycznie pominęliśmy zasadniczy krok: po tym, jak kompilator TypeScriptu generuje AST programu, ale zanim emituje kod, wykonuje na kodzie sprawdzanie typów.

Program do sprawdzania typów

Specjalny program, który sprawdza bezpieczeństwo typów w kodzie.

W tym sprawdzaniu typów kryje się magia języka TypeScript. W ten sposób TypeScript upewnia się, że program działa zgodnie z oczekiwaniami, nie zawiera oczywistych błędów i na pewno twój szczęśliwy los w primaaprilisowej loterii czeka na ciebie.

Gdy uwzględnimy sprawdzanie typów i generowanie kodu JavaScriptu, proces kompilowania kodu TypeScriptu wygląda mniej więcej tak, jak na rysunku 2.1:

Rysunek 2.1. Kompilowanie i wykonywanie kodu TypeScriptu

Kroki 1–3 są wykonywane przez TSC, natomiast kroki 4–6 przez środowisko uruchomieniowe JavaScriptu, które działa w przeglądarce, NodeJS lub innym wykorzystywanym silniku JavaScriptu.

Kompilatory i środowiska uruchomieniowe JavaScriptu są często umieszczane w jednym programie nazywanym silnikiem. Zazwyczaj to właśnie z nim podejmują interakcję programiści. W ten sposób działa V8 (silnik NodeJS, Chrome i Opera), SpiderMonkey (Firefox), JSCore (Safari) oraz Chakra (Edge). Dzięki takiemu rozwiązaniu JavaScript sprawia wrażenie, jakby był językiem interpretowanym.

W tym procesie typy zdefiniowane w programie są wykorzystywane w krokach 1–2, ale nie w kroku 3. Warto ponownie podkreślić, że TSC, kompilując nasz kod z języka TypeScript do języka JavaScript, nie będzie uwzględniał typów. To oznacza, że typy zdefiniowane w programie nie będą wpływały na generowany wynik programu i będą służyły jedynie do sprawdzania typów. Ta cecha sprawia, że można swobodnie wypróbowywać, modyfikować i udoskonalać typy w programie bez obaw, że uszkodzi to działanie aplikacji.

System typów

Nowoczesne języki programowania mają różne rodzaje systemów typów.

System typów

Zbiór reguł, które program do sprawdzania typów wykorzystuje do przypisywania typów w programie.

Zasadniczo wyróżniamy dwa rodzaje systemów typów: takie, w których kompilator wymaga określenia typu wszystkich obiektów przy użyciu jawnej składni, oraz takie, które potrafią automatycznie wywnioskować typy obiektów. Oba podejścia mają pewne wady i zalety1.

TypeScript czerpie inspiracje z obu systemów typów – możemy dodawać jawne adnotacje typów lub pozwolić TypeScriptowi automatycznie wywnioskować większość typów.

Do jawnego pokazywania kompilatorowi TypeScriptu, jakich typów chcemy użyć, służą adnotacje. Adnotacje mają postać wartość: typ i mówią programowi do sprawdzania typów: „Hej! Widzisz tę wartość? Jej typ to typ”. Przyjrzyjmy się kilku przykładom (w komentarzu na końcu każdego wiersza określiliśmy faktyczny typ zastosowany przez kompilator TypeScriptu):

let a: number = 1 // a jest liczbą

let b: string = ‘hello’ // b jest łańcuchem

let c: boolean = // c jest tablicą wart. logicznych

A gdy chcemy, aby TypeScript sam wywnioskował typy, wystarczy pominąć je i pozostawić to zadanie kompilatorowi:

let a = 1 // a jest liczbą

let b = ‘hello’ // b jest łańcuchem

let c = // c jest tablicą wart. logicznych

Od razu można zauważyć, jak dobrze TypeScript radzi sobie z automatycznym wnioskowaniem typów. Gdy pominęliśmy adnotacje, typy nie zmieniły się! W tej książce będziemy stosować adnotacje tylko wtedy, gdy to konieczne – w pozostałych sytuacjach pozwolimy, aby TypeScript magicznie je wywnioskował.

Zasadniczo dobrze jest pozostawić TypeScriptowi automatyczne wnioskowanie większości typów, minimalizując ilość kodu z jawnie zdefiniowanymi typami.

JavaScript versus TypeScript

Teraz przyjrzyjmy się systemowi typów w TypeScripcie i porównajmy go z systemem typów w JavaScripcie. Tabela 2.1 przedstawia zestawienie. Zrozumienie różnic daje wyobrażenie, w jaki sposób działa TypeScript.

Tabela 2.1. Porównanie systemów typów w JavaScripcie i TypeScripcie

Cecha systemu typów JavaScript TypeScript
------------------------------------------- ------------------------------- --------------------------------
Jak wiązane są typy? dynamicznie statycznie
Czy typy są automatycznie przekształcane? tak nie (z reguły)
Kiedy sprawdzane są typy? w czasie wykonania w czasie kompilacji
Kiedy ujawniają się błędy? w czasie wykonania (z reguły) w czasie kompilacji (z reguły)

Jak wiązane są typy?

Dynamiczne wiązanie typów oznacza, że JavaScript musi tak naprawdę uruchomić nasz program, aby poznać zastosowane w nim typy. JavaScript nie zna typów przed uruchomieniem programu.

TypeScript jest językiem stopniowo typowanym. To oznacza, że TypeScript działa najlepiej, gdy w czasie kompilacji zna typy wszystkich obiektów w programie, ale może skompilować program nawet wtedy, gdy nie zna wszystkich typów. W programie, w którym typy nie zostały zdefiniowane, TypeScript potrafi automatycznie wywnioskować pewne typy i wychwycić niektóre błędy, jednak gdy nie zna wszystkich typów, może przeoczyć wiele błędów, które trafiają do użytkowników.

Stopniowe typowanie bardzo pomaga w migracji istniejącej bazy kodu JavaScriptu bez typów do TypeScriptu z typami (dodatkowe informacje można znaleźć w części „Stopniowa migracja z JavaScriptu do TypeScriptu” na stronie 230), ale w innych sytuacjach należy dążyć do uzyskania 100-procentowego pokrycia dla typów. Takie podejście zostało zastosowane również w tej książce, o ile nie zaznaczyliśmy inaczej.

Czy typy są automatycznie przekształcane?

JavaScript jest językiem o słabym typowaniu. To oznacza, że jeśli wykonamy nieprawidłowe działanie, np. dodamy liczbę do tablicy (jak w rozdziale 1), JavaScript zastosuje wiele reguł w celu odgadnięcia naszych intencji i spróbuje zrobić co może w danej sytuacji. Przeanalizujmy pewien przykład ilustrujący, w jaki sposób JavaScript wyznacza wynik działania 3 + :

1. JavaScript zauważa, że 3 jest liczbą, a jest tablicą.
2. Ponieważ używamy operatora +, zakłada, że chcemy połączyć je ze sobą.
3. W niejawny sposób przekształca 3 w łańcuch, co daje “3”.
4. W niejawny sposób przekształca w łańcuch, co daje “1”.
5. Łączy wyniki, co daje “31”.

Moglibyśmy osiągnąć ten sam efekt również w jawny sposób (eliminując kroki 1, 3 i 4):

3 + ; // daje w wyniku “31”

(3).toString() + .toString() // daje w wyniku “31”

Podczas gdy JavaScript próbuje pomóc, automatycznie wykonując sprytne przekształcenia typów, TypeScript skarży się, gdy podejmujemy nieprawidłowe działanie. Gdy uruchomimy ten sam kod JavaScriptu za pomocą TSC, otrzymamy błąd informujący, że nie można stosować operatora ‘+’ na tych typach:

3 + ; // Błąd TS2365: Nie można zastosować operatora

// ‘+’ do typów ‘3’ i ‘number’.

(3).toString() + .toString() // daje w wyniku “31”

Jeśli podejmiemy działanie, które wydaje się nieprawidłowe, TypeScript zgłasza zażalenie i wycofuje je dopiero wtedy, gdy w jawny sposób wyrazimy nasze intencje. Takie zachowanie ma sens: komu przyszłoby do głowy dodawanie liczby do tablicy w celu otrzymania łańcucha (oczywiście poza Bavmordą, czarownicą JavaScriptu, która siedzi w piwnicy pewnego start-upa i programuje przy blasku świec)?

Tego typu niejawne przekształcania, jakie przeprowadza JavaScript, mogą być źródłem trudnych do zlokalizowania błędów i stanowią zmorę wielu programistów JavaScriptu. To utrudnia pojedynczym inżynierom wykonywanie zadań i dodatkowo komplikuje skalowanie kodu w dużych zespołach, ponieważ każdy członek zespołu musi zrozumieć niejawne założenia przyjęte w kodzie.

W skrócie, gdy przekształcanie typów jest konieczne, należy przeprowadzać je w sposób jawny.

Kiedy sprawdzane są typy?

W większości sytuacji JavaScript nie zwraca uwagi na przekazywane typy i próbuje jak najlepiej dostosować to, co otrzymał, do tego, czego oczekiwał.

Natomiast TypeScript sprawdza kod pod kątem typów w czasie kompilacji (drugi krok na przedstawionej na początku rozdziału liście), dlatego nie trzeba uruchamiać kodu, aby zobaczyć przedstawiony w poprzednim przykładzie błąd. TypeScript statycznie przeanalizuje nasz kod pod kątem tego rodzaju błędów i pokaże je przed uruchomieniem. Jeśli kod nie kompiluje się, często oznacza to, że popełniliśmy błąd i musimy naprawić go, zanim spróbujemy uruchomić kod.

Rysunek 2.2 ilustruje, co się stało po wpisaniu kodu ostatniego przykładu w VSCode (naszym ulubionym edytorze).

Rysunek 2.2. Błąd TypeError zgłoszony przez VSCode

Gdy wybrany edytor kodu ma dobre rozszerzenie TypeScriptu, błąd jest wskazywany już w czasie wpisywania za pomocą czerwonej falistej linii podkreślającej kod. To znacznie skraca czas między napisaniem kodu a dowiadywaniem się o błędzie i poprawianiem kodu w celu wyeliminowania tego błędu.

Kiedy ujawniają się błędy?

JavaScript zgłasza wyjątki lub przeprowadza niejawne przekształcenia typów dopiero w czasie wykonania2. To oznacza, że musimy uruchomić program, aby otrzymać cenną informację o tym, że wykonaliśmy nieprawidłowe działanie. W najlepszym przypadku zachodzi to w czasie testów jednostkowych, w najgorszym – przejawia się w postaci nieprzyjemnego e-maila od użytkownika.

TypeScript zgłasza błędy związane ze składnią i z typami w czasie kompilacji. W praktyce oznacza to, że tego rodzaju błędy pojawiają się w edytorze w czasie pisania kodu. Jest to niesamowite przeżycie dla osób, które nie miały wcześniej okazji programować w językach z typowaniem statycznym i kompilacją przyrostową3.

Niemniej istnieje wiele błędów, których TypeScript nie może wykryć w czasie kompilacji, takich jak: przepełnienie stosu, przerwane połączenia sieciowe czy niepoprawne dane wejściowe, które skutkują zgłoszeniem wyjątku w czasie uruchomienia. Zadaniem TypeScriptu jest wychwycenie w czasie kompilacji wielu błędów, które w przypadku użycia wyłącznie kodu JavaScriptu ujawniłyby się dopiero po uruchomieniu.

Przygotowanie edytora kodu

Skoro wyjaśniliśmy już, w jaki sposób działa kompilator TypeScript Compiler i system typów, pokażemy, jak przygotować edytor do rozpoczęcia pracy z prawdziwym kodem.

Zacznijmy od pobrania edytora kodu, w którym będziemy pisać kod. Lubimy VSCode, ponieważ edytowanie w nim kodu TypeScriptu jest szczególnie wygodne, ale można również użyć Sublime Text, Atom, Vim, WebStorm bądź innego preferowanego edytora. Programiści mają zwykle zdecydowane preferencje dotyczące środowisk IDE, dlatego zostawiamy ci wolny wybór. Jeśli chcesz użyć VSCode, zainstaluj go zgodnie z instrukcjami przedstawionymi na stronie https://code.visualstudio.com/.

Sam kompilator TypeScript Compiler (TSC) jest aplikacją wiersza polecenia napisaną w języku TypeScript4, w związku z tym do jego uruchamiania potrzebny jest NodeJS. Postępuj zgodnie z instrukcjami ze strony https://nodejs.org/en/, aby przygotować NodeJS do działania na swojej maszynie.

W skład środowiska NodeJS wchodzi menedżer pakietów NPM, którego użyjemy do zarządzania zależnościami projektu i zorganizowania kompilacji. Na początku skorzystamy z niego do zainstalowania pakietów TSC oraz TSLint (linter dla TypeScriptu). Zacznijmy od otwarcia terminala i utworzenia nowego folderu, a następnie zainicjalizujmy w nim nowy projekt NPM:

# Utwórz nowy folder

mkdir chapter-2

cd chapter-2

# Zainicjalizuj nowy projekt NPM (postępuj zgodnie z instrukcją)

npm init

# Zainstaluj TSC, TSLint i deklaracje typów dla NodeJS

npm install --save-dev typescript tslint @types/node

tsconfig.json

Każdy projekt TypeScriptu powinien zawierać w katalogu głównym plik o nazwie tsconfig.json. W pliku tsconfig.json projekty TypeScriptu definiują m.in. które pliki powinny być kompilowane, do którego katalogu mają być kompilowane i która wersja JavaScriptu ma być generowana.

Utwórzmy nowy plik o nazwie tsconfig.json w katalogu głównym (touch tsconfig.json)5, a następnie otwórzmy go w edytorze kodu i dodajmy do niego poniższe ustawienia:

{

“compilerOptions”: {

“lib”: ,

“module”: “commonjs”,

“outDir”: “dist”,

“sourceMap”: true,

“strict”: true,

“target”: “es2015”

},

“include”:

}

Przeanalizujmy pokrótce wybrane opcje i ich znaczenie (tabela 2.2):

Tabela 2.2. Opcje tsconfig.json

Opcja Opis
--------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
include W których folderach TSC ma szukać plików TypeScript?
lib Jakie API można założyć, że istnieją w środowisku, w którym będzie uruchamiany kod? Dotyczy to takich metod, jak: Function.prototype.bind w ES5, Object.assign, w ES2015 i document.querySelector w DOM.
module Do jakiego systemu modułów TSC ma kompilować nasz kod (CommonJS, SystemJS, ES2015 itd.)?
outDir W jakim folderze TSC ma umieścić wygenerowany kod JavaScriptu?
strict Zastosowanie trybu ścisłego (najbardziej restrykcyjnego) podczas sprawdzania nieprawidłowości w kodzie. Ta opcja wymaga, aby w całym kodzie były stosowane odpowiednie typy. Będziemy używać tego ustawienia we wszystkich prezentowanych w tej książce przykładach i warto stosować je we wszystkich projektach TypeScript.
target Do jakiej wersji JavaScript ma być kompilowany kod (ES3, ES5, ES2015, ES2016 itd.)?

To tylko kilka wybranych opcji – tsconfig.json oferuje ich dziesiątki i ciągle dodawane są nowe6. W praktyce jednak rzadko dokonujemy zmian, poza dostosowywaniem ustawień module i target ze względu na użycie nowego narzędzia typu module bundler, dodaniem “dom” do lib w przypadku pisania kodu TypeScriptu dla przeglądarki (patrz rozdział 12) lub dostosowywaniem poziomu rygorystyczności podczas migracji istniejącego kodu JavaScriptu do TypeScriptu (patrz „Stopniowa migracja z JavaScriptu do TypeScriptu” na stronie 230). Pełną i aktualną listę wspieranych opcji można znaleźć w oficjalnej dokumentacji na stronie internetowej TypeScriptu (https://www.typescriptlang.org/docs/handbook/compiler-options.html).

Warto mieć świadomość, że choć konfigurowanie TSC przy użyciu pliku tsconfig.json jest wygodne, ponieważ pozwala na wprowadzenie tej konfiguracji do systemu kontroli wersji, większość opcji TSC można również ustawić za pośrednictwem wiersza poleceń. Aby zobaczyć listę opcji dostępnych w wierszu poleceń, należy uruchomić polecenie ./node_modules/.bin/tsc --help.

tslint.json

Projekt powinien zawsze zawierać plik tslint.json z konfiguracją TSLint, definiujący konwencje stylistyczne, jakie mają być stosowane w kodzie (tabulatory czy spacje itp.).

Wykorzystywanie narzędzia TSLint nie jest wymagane, ale zdecydowanie zalecamy stosowanie go we wszystkich projektach TypeScriptu w celu wymuszania spójnego stylu w kodzie. Dzięki temu nie będziemy marnować czasu na sprzeczanie się ze współpracownikami o styl w czasie przeglądów kodu.

Następujące polecenie wygeneruje plik tslint.json z domyślną konfiguracją TSLint:

./node_modules/.bin/tslint --init

Następnie możemy dodać do niej przesłonięcia, które wymuszają preferowany styl. Na przykład nasz plik tslint.json wygląda następująco:

{

“defaultSeverity”: “error”,

“extends”: ,

“rules”: {

“semicolon”: false,

“trailing-comma”: false

}

}

Pełną listę dostępnych reguł można znaleźć w dokumentacji TSLint (https://palantir.github.io/tslint/rules/). Można również dodawać niestandardowe reguły lub instalować dodatkowe presety, np. dla ReactJS (https://www.npmjs.com/package/tslint-react).

index.ts

Skoro przygotowaliśmy już pliki tsconfig.json oraz tslint.json, możemy utworzyć folder src zawierający nasz pierwszy plik TypeScriptu:

mkdir src

touch src/index.ts

Struktura folderów w tym projekcie powinna wyglądać następująco:

Otwórzmy plik src/index.ts w edytorze kodu i wpiszmy następujacy kod TypeScriptu:

console.log(‘Hello TypeScript!’)

A następnie skompilujmy i uruchommy kod TypeScriptu:

# Kompiluj TypeScript przy użyciu TSC

./node_modules/.bin/tsc

# Uruchom kod przy użyciu NodeJS

node ./dist/index.js

Jeśli wszystkie kroki zostały prawidłowo wykonane, kod powinien się uruchomić, a w konsoli wyświetlić się pojedynczy napis:

Hello TypeScript!

W taki właśnie sposób przygotowaliśmy i uruchomiliśmy od podstaw nasz pierwszy projekt TypeScriptu. Doskonale!

Ponieważ niektórzy czytelnicy po raz pierwszy mieli okazję konfigurować projekt TypeScriptu od podstaw, omówiliśmy każdy kolejny krok, by zaprezentować wszystkie ruchome elementy. Aby przyśpieszyć ten proces, w przyszłości można zastosować pewne skróty:

- Zainstalować ts-node (https://www.npmjs.com/package/ts-node) i użyć go do kompilowania oraz uruchamiania kodu TypeScriptu za pomocą jednego polecenia.
- Użyć pomocniczego narzędzia, takiego jak typescript-node-starter (https://github.com/Microsoft/TypeScript-Node-Starter), do szybkiego generowania struktury folderów.

Ćwiczenia

Skoro dysponujesz już skonfigurowanym środowiskiem, otwórz plik src/index.ts w edytorze kodu. Wpisz następujący kod:

let a = 1 + 2

let b = a + 3

let c = {

apple: a,

banana: b

}

let d = c.apple * 4

A teraz umieść kursor nad a, b, c i d, zwracając uwagę, w jaki sposób TypeScript samodzielnie wnioskuje typy zmiennych: a to number, b to number, c to obiekt o określonym kształcie, d to również number (rysunek 2.3).

Rysunek 2.3. Wnioskowanie typów w TypeScripcie

Poeksperymentuj z kodem. Sprawdź, czy potrafisz:

- Sprawić, że TypeScript wyświetli czerwoną falistą linię, gdy zrobisz coś nieprawidłowo (co nazywamy „zgłaszaniem błędu TypeError”).
- Przeczytać TypeError i spróbować zrozumieć, co on oznacza.
- Naprawić błąd TypeError, aby czerwona falista linia zniknęła.

Jeśli jesteś ambitny, spróbuj napisać kod, dla którego TypeScript nie będzie potrafił wywnioskować typu.Przypisy

Przedmowa

1 Oto przykład dla osób niezaznajomionych z językiem JavaScript. Gdy masz obiekt o i chcesz dodać do niego właściwość k o wartości 3, możesz bezpośrednio go zmodyfikować (o.k = 3) lub zastosować zmianę na o, co prowadzi do utworzenia nowego obiektu (let p = {...o, k: 3}).

1. Wprowadzenie

1 Zależnie od tego, który język z typowaniem statycznym wykorzystujesz, „nieprawidłowe” może mieć różne znaczenie – od programów, które nagle przerywają pracę, po takie, których działanie nie ma sensu.

2 Jeśli nie do końca rozumiesz, co oznacza „poziom typów”, nic nie szkodzi. To zagadnienie omówimy szczegółowo w kolejnych rozdziałach.

2. TypeScript: Ogólny obraz

1 Języki programowania obejmują całe spektrum: JavaScript, Python i Ruby wnioskują typy w czasie wykonania, Haskell i OCaml wnioskują i sprawdzają brakujące typy w czasie kompilacji, Scala i TypeScript wymagają jawnego adnotowania niektórych typów i wnioskują oraz sprawdzają pozostałe w czasie kompilacji, natomiast Java i C wymagają jawnych adnotacji dla prawie wszystkiego, co sprawdzają w czasie kompilacji.

2 Tak dla jasności: JavaScript wskazuje błędy składni i kilka wybranych pomyłek (takich jak deklaracje const o powtarzających się nazwach w tym samym zakresie) po sparsowaniu programu, ale przed jego uruchomieniem. Gdy parsujemy kod JavaScriptu w ramach procesu budowania (np. przy użyciu kompilatora Babel), możemy ujawniać te błędy w czasie budowania.

3 Języki z kompilacją przyrostową umożliwiają szybką rekompilację po dokonaniu małej zmiany, ponieważ nie wymagają rekompilacji całego programu (łącznie z częściami, które nie uległy zmianie).

4 Dzięki czemu TSC zalicza się do mistycznej grupy kompilatorów nazywanych kompilatorami self-hosting, czyli kompilatorami, które same się kompilują.

5 W tym ćwiczeniu własnoręcznie tworzymy plik tsconfig.json. W przyszłych projektach TypeScriptu do jego automatycznego wygenerowania można użyć wbudowanego w TSC polecenia inicjalizacji: ./node_modules/.bin/tsc --init.

6 Aby komunikaty o błędach były wyświetlane w polskiej wersji językowej, można użyć opcji: „typescript.locale”: „pl”. Warto dodać ją również do pliku ustawień VSCode (settings.json), aby zobaczyć polską wersję także w edytorze kodu (przyp. tłum.).
mniej..

BESTSELLERY

Kategorie: