TypeScript – pierwsze kroki. Przestrzenie nazw w TypeScript.

Gdy pisałem moją wrześniową grę co miesiąc, nie znałem jeszcze dobrego sposobu na modularyzację kodu w TypeScript. Gra nie była specjalnie duża ale i tak brak modułów spowodował, że kod był cięższy do czytania i utrzymania.

Dziś przedstawię rozwiązanie tego problemu. Będą to podstawowych technik wykorzystania TSowych modułów. Na początek opiszę idealnie nadające się do dzielenia kodu na utrzymywalne i czytelne fragmenty – przestrzenie nazw czyli znane wszystkim użytkownikom Javy, C++ czy C#, namespace`y.

Przestrzenie nazw w TypeScript

Aby stworzyć przestrzeń nazw w TypeScript wystarczy użyć operatora namespace, po którym podajemy nazwę tworzonego modułu i parę nawiasów klamrowych, które zawierać będą kod, który chcemy enkapsulować. Oto przykład:

W nazwach tak tworzonych modułów, możemy używać kropek co od razu budje odpowiednią hierarchie przestrzeni nazw:

Nawet jeśli wcześniej nie określiłem żadnej z tych przestrzeni, ten kod zadzaiała. Automatycznie tworzę trzy zagnieżdżone moduły: dataParser, który zawiera się w utilities, który z kolei jest częścią większego modułu app. Oczywiście moduły mogą otrzymywać dowolne nazwy zgodne z JS’ową konwencją nazywania zmiennych.

Spójrzmy na konkretniejszy przykład. Stworzę przestrzeń nazw classes, w której zadeklaruję nową klasę:

Klasa Dog, nie będzie teraz dostępna poza przestrzenią nazw. Można się do niej odwoływać tylko wewnątrz classes. Ten kod, wpisany pod przestrzenią nazw, wywoła błąd:

Dog nie jest dostępne w globalnym zakresie. Edytor zgłosi po prostu błąd, że zmienna Dog nie została zadeklarowana.

W zwykłym JavaScripcie, aby dostać się do przestrzeni nazw (która zazwyczaj jest po prostu zwykłym obiektem), wystarczyło użyć notacji z kropką. W taki sposób:

W TypeScript także musimy to zrobić. Program musi wiedzieć z jakiej przestrzeni nazw chcemy skorzystać. W końcu dwie różne przestrzenie, mogą mieć w sobie dane o takich samych identyfikatorach.

Jednak edytor wciąż zgłasza błąd:

Moduły W TypeScript, przestrzenie nazw

Błąd mówi, że w classes nie istnieje zmienna o nazwie Dog. Oczywiście to nie prawda. Jednak TypeScript jest na tyle mądry, że nie pozwala wyciekać z modułów wszystkiemu jak leci (co jest problemem w zwykłym JS). Jeżeli chcemy aby jakaś część modułu była dostępna po za nim, musimy wyraźnie to wskazać. Aby to zrobić, wystarczy przed interesującym nas elementem dopisać export:

Teraz klasa Dog jest eksportowana poza przestrzeń nazw. Pierwsza deklaracja zmiennej pod classes nie generuje już błędu. Druga za to tak, ponieważ klasa Cat nie jest dostępna poza modułem (brak export).

Jeżeli przestrzeń nazw jest zagnieżdżona w innych przestrzeniach, aby dostać się do niej z zewnątrz, należy po kropkach wymienić wszystkie przestrzenie patrząc „od góry”, czyli od zewnątrz. Zupełnie jak z obiektami w JavaScript.

Jeśli na przykład chcę wyłuskać pole z takiej przestrzeni:

Musiałbym wpisać:

Ale z poziomu modułu app, wystarczyłoby już tylko:

Co ciekawe, nic nie stoi na przeszkodzie aby używać elementów jednej przestrzeń wewnątrz drugiej, niezależnej przestrzeni. Pod warunkiem oczywiście, że elementy te są najpierw eksportowane:

Tutaj, wewnątrz modułu classes odwołuje się do interfejsu animal z wnętrza przestrzeni interfaces, która z kolei znajduje się w GUI, siedzącego w app. Może ten przykład jest mało praktyczny, ale technicznie nic nie stoi na przeszkodzie aby stworzyć taki mechanizm.

Długie przestrzenie nazw mogą być kłopotliwe, zwłaszcza jeśli odwołujemy się do nich wiele razy w innym modle. Na szczęście jest sposób i na to. Wewnątrz aktualnego zakresu zmiennych, możemy stworzyć coś jakby alias dla długich przestrzeni. Robi się to za pomocą operatora import:

Po import podaję alias do którego chcę przypisać przestrzeń lub nawet konkretny jej element. Następnie stawiam znak równości i długą przestrzeń nazw.

W powyższym przykładzie wyglądałoby to tak:

Tworzę alias tylko do interfaces, na wypadek jakby zawierał jakieś elementy oprócz animal, które mnie interesują. Jak widać w niczym to nie przeszkadza. Tam gdzie wcześniej odwoływałem się do pełnej ścieżki przestrzeni nazw, teraz wpisuję tylko alias a po jego nazwie mogę normalnie używać notacji z kropką aby dostać się do znajdujących się głębiej elementów.

To wszystko jeśli chodzi o podstawy przestrzeni nazw w TypeScript, jednak nie wszystko jeśli chodzi o modularyzację kodu. Do tematu powrócę w kolejnym poście z serii.

Jeżeli chcesz być na bieżąco z postami na blogu zachęcam do polubienia mojej strony na facebooku. Zawsze zamieszczam tam informacje o wszystkich nowościach. Jest to też dobre miejsce na kontakt ze mną. Na wszystkie pytania zawsze odpowiem :).

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *