Node.js dla początkujących - Część 17: Wprowadzenie do TypeScript
Mateusz Kędziora

Cześć! Jeśli jesteś na początku swojej drogi z JavaScriptem, być może słyszałeś o czymś takim jak TypeScript. W tym krótkim artykule rozłoże przed Tobą TypeScript na czynniki pierwsze i pokaże, dlaczego warto się nim zainteresować. Zobaczymy, jak zainstalować potrzebne narzędzia, poznamy podstawowe typy danych i interfejsy, a na koniec zadasz sobie prostą pracę domową, która utrwali Twoją wiedzę. Zaczynamy!
Co to jest TypeScript?
TypeScript to język programowania, który rozszerza możliwości JavaScriptu poprzez dodanie statycznego typowania. Co to oznacza w praktyce? W tradycyjnym JavaScripcie typ zmiennej jest określany dynamicznie, w trakcie działania programu. To elastyczne podejście ma jednak swoje wady – błędy typów mogą ujawnić się dopiero w trakcie testów lub, co gorsza, już po wdrożeniu aplikacji.
TypeScript pozwala na zdefiniowanie typów zmiennych już na etapie pisania kodu. Dzięki temu kompilator (narzędzie, które tłumaczy kod TypeScript na JavaScript) może wychwycić wiele potencjalnych błędów jeszcze przed uruchomieniem programu. To trochę jak dodatkowa para oczu, która czuwa nad poprawnością Twojego kodu.
TypeScript jest nadzbiorem JavaScriptu, co oznacza, że każdy poprawny kod JavaScript jest również poprawnym kodem TypeScript. Możesz więc stopniowo wprowadzać TypeScript do istniejących projektów JavaScript, bez konieczności ich całkowitego przepisywania.
Dlaczego warto używać TypeScripta?
Oto kilka kluczowych korzyści płynących z używania TypeScripta:
- Wczesne wykrywanie błędów: Kompilator TypeScripta pomaga wychwycić błędy typów na etapie kompilacji, co oszczędza czas i nerwy podczas debugowania.
- Lepsza czytelność i utrzymywalność kodu: Jawne typowanie sprawia, że kod staje się bardziej zrozumiały dla innych programistów (i dla Ciebie samego po kilku miesiącach).
- Wsparcie dla refaktoryzacji: Zmiany w kodzie są bezpieczniejsze, ponieważ kompilator TypeScripta pomoże Ci zidentyfikować wszystkie miejsca, które wymagają aktualizacji w związku ze zmianą typu.
- Lepsze wsparcie IDE: Edytory kodu, takie jak Visual Studio Code, oferują zaawansowane funkcje autouzupełniania, podpowiedzi i nawigacji po kodzie TypeScript.
Instalacja i uruchamianie kodu TypeScript (z użyciem swc)
Do kompilacji kodu TypeScript na JavaScript użyjemy swc (Speedy Web Compiler), który jest znacznie szybszy od tradycyjnego kompilatora tsc
.
Instalacja Node.js i npm (lub yarn/pnpm): Upewnij się, że masz zainstalowane Node.js i menedżer pakietów npm (lub yarn/pnpm). Poradnik jak je zainstalować znajduje się tutaj.
Inicjalizacja projektu: Utwórz nowy folder projektu i w terminalu przejdź do niego, a następnie zainicjalizuj nowy projekt Node.js:
mkdir typescript-intro cd typescript-intro npm init -y # lub yarn init -y / pnpm init
Instalacja swc i typów dla Node.js (opcjonalnie):
npm install --save-dev @swc/cli @swc/core typescript @types/node
Konfiguracja kompilacji (swc): Dodaj skrypt do pliku
package.json
:"scripts": { "build": "swc src -d dist --source-maps", "start": "node dist/index.js", "dev": "npm run build && npm run start" },
Stworzenie pliku konfiguracyjnego
tsconfig.json
: W głównym folderze projektu utwórz pliktsconfig.json
z podstawową konfiguracją:{ "compilerOptions": { "target": "es2020", "module": "commonjs", "outDir": "./dist", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true } }
Stworzenie folderu
src
i plikuindex.ts
: Utwórz foldersrc
i w nim plikindex.ts
, w którym będziemy pisać kod TypeScript.
Teraz możesz pisać kod TypeScript w pliku src/index.ts
. Aby go skompilować, uruchom polecenie npm run build
. Skompilowany kod JavaScript znajdzie się w folderze dist
. Uruchomienie skompilowanego kodu odbywa się za pomocą npm run start
. Polecenie npm run dev
skompiluje i uruchomi kod za jednym zamachem.
Podstawowe typy danych w TypeScript
TypeScript oferuje szeroki zakres typów danych, które pozwalają na precyzyjne określenie rodzaju wartości przechowywanych w zmiennych. Oto kilka podstawowych typów:
number
: Typ liczbowy, obejmujący zarówno liczby całkowite, jak i zmiennoprzecinkowe.let wiek: number = 30; let pi: number = 3.14;
string
: Typ tekstowy.let imie: string = "Jan"; let powitanie: string = "Witaj, " + imie + "!";
boolean
: Typ logiczny, przyjmujący wartościtrue
lubfalse
.let czyJestDorosly: boolean = true;
any
: Typ dynamiczny, pozwalający na przechowywanie wartości dowolnego typu (należy unikać, jeśli to możliwe).let cos: any = "Tekst"; cos = 123;
Array
: Typ tablicowy.let liczby: number[] = [1, 2, 3, 4, 5]; let imiona: string[] = ["Anna", "Piotr", "Maria"]; let mieszane: any[] = [1, "tekst", true]; // Unikamy any[] let liczby2: Array<number> = [1,2,3]; // Drugi sposób zapisu
tuple
: Typ krotki, pozwalający na przechowywanie wartości o różnych typach w ustalonej kolejności.let osoba: [string, number] = ["Jan Kowalski", 30];
enum
: Typ wyliczeniowy, pozwalający na zdefiniowanie zbioru nazwanych wartości.enum StatusZamowienia { Oczekujące, WRealizacji, Zakończone, Anulowane } let status: StatusZamowienia = StatusZamowienia.WRealizacji; console.log(status); // Wypisze 1
void
: Typ oznaczający brak wartości (np. dla funkcji, która nic nie zwraca).function wyswietlPowitanie(imie: string): void { console.log("Witaj, " + imie + "!"); }
null
iundefined
: Typy reprezentujące odpowiednio brak wartości i niezdefiniowaną wartość.let zmiennaNull: null = null; let zmiennaUndefined: undefined = undefined;
Interfejsy
Interfejsy w TypeScripcie służą do definiowania kontraktów, czyli struktur danych. Określają one, jakie właściwości i metody powinien posiadać obiekt danego typu.
interface Osoba {
imie: string;
wiek: number;
adres?: string; // Właściwość opcjonalna
powitaj(): string;
}
let jan: Osoba = {
imie: "Jan",
wiek: 30,
powitaj(): string {
return "Cześć, nazywam się " + this.imie;
}
};
function wyswietlDaneOsoby(osoba: Osoba): void {
console.log("Imię: " + osoba.imie);
console.log("Wiek: " + osoba.wiek);
if (osoba.adres) {
console.log("Adres: " + osoba.adres);
}
console.log(osoba.powitaj());
}
wyswietlDaneOsoby(jan);
// Próba utworzenia obiektu niespełniającego interfejsu spowoduje błąd kompilacji
// let nowaOsoba = { imie: "Kasia", wzrost: 160 }; // Błąd: Brak właściwości 'wiek' i 'powitaj'
interface Programista extends Osoba {
jezykProgramowania: string;
}
let piotr: Programista = {
imie: "Piotr",
wiek: 25,
jezykProgramowania: "TypeScript",
powitaj(): string {
return "Cześć, jestem programistą " + this.jezykProgramowania + " i mam na imię " + this.imie;
}
};
wyswietlDaneOsoby(piotr);
console.log("Język programowania: " + piotr.jezykProgramowania);
W powyższym przykładzie zdefiniowaliśmy interfejs Osoba
, który określa, że obiekt powinien posiadać właściwości imie
(typu string
), wiek
(typu number
) oraz opcjonalną właściwość adres
(typu string
) i metodę powitaj()
, która zwraca string. Następnie stworzyliśmy obiekt jan
, który implementuje ten interfejs. Funkcja wyswietlDaneOsoby
przyjmuje jako argument obiekt typu Osoba
i wyświetla jego dane.
Pokazaliśmy też, co się stanie, gdy spróbujemy stworzyć obiekt, który nie spełnia interfejsu – kompilator TypeScripta zgłosi błąd. To właśnie jest największa zaleta statycznego typowania!
Dodatkowo, zaprezentowaliśmy dziedziczenie interfejsów za pomocą słowa kluczowego extends
. Interfejs Programista
dziedziczy po interfejsie Osoba
i dodaje nową właściwość jezykProgramowania
.
Typy Unii (Union Types)
Typy unii pozwalają na określenie, że zmienna może przechowywać wartość jednego z kilku typów.
function pobierzWartosc(wartosc: string | number): string {
if (typeof wartosc === 'string') {
return "Podałeś tekst: " + wartosc;
} else {
return "Podałeś liczbę: " + wartosc;
}
}
console.log(pobierzWartosc("Hello")); // Podałeś tekst: Hello
console.log(pobierzWartosc(123)); // Podałeś liczbę: 123
Typy Generyczne (Generics)
Typy generyczne pozwalają na pisanie kodu, który może działać z różnymi typami danych, bez konieczności jego powielania.
function zwrocPierwszyElement<T>(tablica: T[]): T | undefined {
return tablica[0];
}
let liczbyGen: number[] = [1, 2, 3];
let tekstGen: string[] = ["a", "b", "c"];
console.log(zwrocPierwszyElement<number>(liczbyGen)); // 1
console.log(zwrocPierwszyElement<string>(tekstGen)); // a
W tym przykładzie funkcja zwrocPierwszyElement
może przyjmować tablicę dowolnego typu (T[]
) i zwracać jej pierwszy element tego samego typu (T
).
Praca Domowa
Teraz czas na małe ćwiczenie, które pomoże Ci utrwalić zdobytą wiedzę:
- Stwórz interfejs
Produkt
z właściwościami:nazwa
(string),cena
(number),opis
(string, opcjonalny) ikategoria
(enum:Spożywcze
,Elektronika
,Odzież
). - Stwórz kilka obiektów implementujących interfejs
Produkt
. - Napisz funkcję, która przyjmuje tablicę produktów i wyświetla ich nazwy i ceny.
- Napisz funkcję, która filtruje tablicę produktów po kategorii i zwraca nową tablicę zawierającą tylko produkty z wybranej kategorii.
- Użyj typów unii aby stworzyć funkcję, która przyjmuje argument typu string lub number i zwraca jego długość (dla stringa) lub wartość (dla numbera).
Podsumowanie
Gratulacje! Dotarłeś do końca tego wprowadzenia do TypeScripta. Poznaliśmy podstawowe typy danych, interfejsy, typy unii i generyczne. Zobaczyłeś, jak TypeScript może pomóc w pisaniu bardziej czytelnego, bezpiecznego i łatwiejszego w utrzymaniu kodu.
Pamiętaj, że praktyka czyni mistrza. Zachęcam Cię do samodzielnego eksperymentowania z TypeScriptem i rozwiązywania zadań. Przeglądaj dokumentację TypeScripta i szukaj inspiracji w kodzie innych programistów.
Jeśli spodobał Ci się ten artykuł, koniecznie zajrzyj do innych wpisów na moim blogu, gdzie znajdziesz więcej informacji na temat JavaScriptu i innych technologii webowych. Do zobaczenia w kolejnych artykułach!
Polecane artykuły
Docker vs Kubernetes: Który dla Ciebie w 2025?
Docker i Kubernetes objaśnione! Która technologia lepsza dla początkujących w 2025? Porównanie, przykłady i przyszłość.
Mateusz Kędziora
DevOps: Automatyzacja zadań sysadmina dla programistów
Zautomatyzuj pracę sysadmina w środowisku DevOps! Praktyczne przykłady, skrypty, Ansible, Terraform, Prometheus i Grafana.
Mateusz Kędziora
Automatyzacja Linux/macOS z Bash: Praktyczny Przewodnik
Zacznij automatyzować system Linux/macOS z Bash! Dowiedz się, czym jest Bash, jak pisać skrypty i używać podstawowych komend.
Mateusz Kędziora