TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

6 marca, 2024

Wstęp

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Wstęp

Co to jest TypeScript i dlaczego warto go używać?

TypeScript, zaprojektowany i rozwijany przez Microsoft, to język programowania będący nadzbiorem JavaScript. Oznacza to, że każdy program napisany w JavaScript jest również programem TypeScript. Co czyni TypeScript wyjątkowym, to dodatkowa warstwa statycznych typów. Dzięki temu deweloperzy mogą pisać bardziej przejrzysty i łatwiejszy w utrzymaniu kod, co jest kluczowe, zwłaszcza w dużych projektach.

Korzyści płynące z użycia TypeScript są znaczące:

  1. Poprawa jakości kodu: TypeScript pomaga w wykrywaniu błędów na wczesnym etapie, jeszcze przed uruchomieniem kodu.
  2. Lepsze narzędzia: Dzięki statycznym typom, edytory i środowiska programistyczne mogą oferować lepsze wsparcie, takie jak autouzupełnianie kodu i refaktoryzacja.
  3. Łatwiejsze zarządzanie: W dużych projektach, gdzie wielu deweloperów pracuje nad tym samym kodem, TypeScript zapewnia lepszą organizację i zrozumienie struktury kodu.

Przejdźmy teraz do konkretów i zobaczmy, jak można zacząć pracę z TypeScript w 10 prostych krokach.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 1: Konfiguracja Środowiska

Instalacja Node.js i NPM

Aby zacząć pracę z TypeScript, najpierw musisz mieć zainstalowany Node.js i NPM (Node Package Manager). Node.js to środowisko uruchomieniowe pozwalające na wykonywanie kodu JavaScript poza przeglądarką, a NPM to menedżer pakietów, który ułatwia instalację i zarządzanie bibliotekami w Twoich projektach.

  1. Pobierz i zainstaluj Node.js ze strony oficjalnej strony Node.js.
  2. Po zainstalowaniu otwórz terminal i sprawdź wersję Node.js i NPM, wpisując node -v i npm -v.

Instalacja TypeScript

Gdy masz już Node.js i NPM, możesz łatwo zainstalować TypeScript globalnie w swoim systemie:

npm install -g typescript

Po instalacji, sprawdź wersję TypeScript, wpisując tsc -v w terminalu. tsc (TypeScript Compiler) to kompilator TypeScript, który przekształca kod TypeScript na JavaScript.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 2: Pierwszy Skrypt TypeScript

Tworzenie i kompilacja pierwszego pliku .ts

Po pomyślnej instalacji TypeScript, stwórzmy Twój pierwszy skrypt. TypeScript to język, który wymaga kompilacji do JavaScript, aby mógł być rozumiany przez przeglądarki lub środowiska uruchomieniowe, takie jak Node.js.

  1. Tworzenie pliku TypeScript:

    • Utwórz nowy folder na swój projekt.
    • Otwórz folder w swoim ulubionym edytorze kodu (na przykład Visual Studio Code).
    • Utwórz nowy plik o nazwie hello.ts.
  2. Pisanie prostego skryptu: W pliku hello.ts, wpisz poniższy kod:

let message: string = 'Witaj, TypeScript!';
console.log(message);
  1. W tym prostym skrypcie deklarujesz zmienną message typu string i przypisujesz jej tekst. Następnie używasz console.log do wyświetlenia wartości zmiennej w konsoli.

  2. Kompilacja kodu TypeScript do JavaScript:

    • Otwórz terminal.
    • Przejdź do folderu z projektem.
    • Uruchom polecenie tsc hello.ts.

    Kompilator tsc przekształci plik hello.ts w plik hello.js, który jest zrozumiały dla środowiska wykonawczego JavaScript.

  3. Uruchomienie skompilowanego skryptu:

    • W terminalu, uruchom skrypt, wpisując node hello.js.
    • Powinieneś zobaczyć w konsoli napis „Witaj, TypeScript!”

Gratulacje! Właśnie napisałeś i uruchomiłeś swój pierwszy skrypt TypeScript.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 3: Typy Zmiennych w TypeScript

TypeScript dodaje do JavaScript warstwę typów, co pozwala na precyzyjne określanie, jakiego rodzaju dane mogą być przechowywane i manipulowane w zmiennych. Oto podstawowe typy danych w TypeScript:

  1. Number: Reprezentuje zarówno liczby całkowite, jak i zmiennoprzecinkowe. Na przykład: let age: number = 25;
  2. String: Reprezentuje ciągi znaków. Można używać pojedynczych ('), podwójnych (") lub backticków (`) do definiowania łańcuchów znaków. Na przykład: let name: string = 'Anna';
  3. Boolean: Reprezentuje wartość prawda/fałsz. Na przykład: let isOpen: boolean = true;
  4. Array: Reprezentuje listę elementów tego samego typu. Można określić tablice na dwa sposoby – za pomocą typu[] lub generycznego Array<typ>. Na przykład: let numbers: number[] = [1, 2, 3]; lub let numbers: Array<number> = [1, 2, 3];
  5. Tuple: Reprezentuje tablicę o stałej liczbie elementów o znanych, ale różnych typach. Na przykład: let person: [string, number] = ['Anna', 25];
  6. Enum: Umożliwia zdefiniowanie zestawu nazwanych stałych numerycznych. Na przykład: enum Color {Red, Green, Blue}; teraz Color.Red może być użyte jako wartość.
  7. Any: Reprezentuje dowolny typ danych; używany, gdy nie jesteśmy pewni, jakiego typu będzie zmienna. Należy używać ostrożnie, ponieważ omija korzyści płynące z typowania.
  8. Void, Null i Undefined: Reprezentują brak wartości lub brak typu. Są używane głównie w kontekście funkcji, gdzie void wskazuje na to, że funkcja nie zwraca żadnej wartości.

Korzystanie z typów pozwala na pisanie bardziej przewidywalnego i bezpiecznego kodu, ponieważ kompilator TypeScript może wykrywać błędy dotyczące typów na etapie kompilacji.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 4: Interfejsy i Klasy

TypeScript poszerza możliwości JavaScript o interfejsy i klasy, co sprawia, że jest doskonałym narzędziem do pisania bardziej zorganizowanego i skalowalnego kodu w dużych aplikacjach.

Definiowanie i Implementacja Interfejsów

Interfejsy w TypeScript pozwalają zdefiniować strukturę dla obiektów, klasy, a nawet funkcji. Służą jako kontrakty, które muszą być spełnione przez obiekt implementujący interfejs.

  • Tworzenie interfejsu:
interface Osoba {
    imie: string;
    wiek: number;
    powitaj(): string;
}
console.log(message);
  • Implementacja interfejsu: Możesz teraz użyć interfejsu Osoba do zdefiniowania obiektu:
let pracownik: Osoba = {
    imie: 'Jan',
    wiek: 30,
    powitaj() {
        return `Cześć, mam na imię ${this.imie} i mam ${this.wiek} lat.`;
    }
};

Tworzenie i Dziedziczenie Klas

Klasy w TypeScript to rozbudowanie koncepcji znanych z JavaScript ES6. Pozwalają one na bardziej strukturalne podejście do obiektowo zorientowanego programowania.

  • Definiowanie klasy:

class Osoba {
    imie: string;
    wiek: number;

    constructor(imie: string, wiek: number) {
        this.imie = imie;
        this.wiek = wiek;
    }

    powitaj() {
        return `Cześć, mam na imię ${this.imie} i mam ${this.wiek} lat.`;
    }
}
  • Dziedziczenie:

TypeScript umożliwia dziedziczenie klas, co pozwala na tworzenie nowych klas na bazie istniejących.

class Pracownik extends Osoba {
    stanowisko: string;

    constructor(imie: string, wiek: number, stanowisko: string) {
        super(imie, wiek);
        this.stanowisko = stanowisko;
    }

    powitaj() {
        return `${super.powitaj()} Pracuję jako ${this.stanowisko}.`;
    }
}

Wykorzystanie interfejsów i klas w TypeScript sprawia, że zarządzanie kodem staje się bardziej uporządkowane i przewidywalne, a także ułatwia współpracę w zespołach.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 5: Funkcje i Generics

TypeScript oferuje rozbudowane możliwości definiowania funkcji, włączając obsługę typów w parametrach i wartościach zwracanych. Dodatkowo, generyki pozwalają na tworzenie komponentów, które mogą pracować z różnymi typami, nie tracąc przy tym na bezpieczeństwie typów.

Tworzenie funkcji

  • Funkcje z typami: Możesz określić typy dla parametrów i wartości zwracanych:

function powitaj(imie: string, wiek: number): string {
    return `Cześć, mam na imię ${imie} i mam ${wiek} lat.`;
}
  • Funkcje strzałkowe; TypeScript wspiera również tzw. arrow functions, co pozwala na bardziej zwięzłą składnię:
const dodaj = (a: number, b: number): number => a + b;

Używanie generyków

Generyki to potężne narzędzie, które umożliwia tworzenie komponentów, które mogą pracować z różnymi typami danych. Oto prosty przykład generycznej funkcji:

  • Funkcja generyczna:

function pierwszyElement(tablica: Type[]): Type {
    return tablica[0];
}

Możesz użyć tej funkcji z tablicami różnych typów, zachowując przy tym bezpieczeństwo typów:

const liczby = [1, 2, 3];
const pierwszaLiczba = pierwszyElement(liczby); // 1

const napisy = ['a', 'b', 'c'];
const pierwszyNapis = pierwszyElement(napisy); // 'a'

Generyki w TypeScript są szczególnie przydatne w większych i bardziej złożonych projektach, gdzie elastyczność w obsłudze różnych typów może znacząco poprawić jakość kodu.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 6: Moduły i Przestrzenie Nazw

Moduły i przestrzenie nazw w TypeScript służą do organizowania kodu, zapobiegania konfliktom nazw i promowania ponownego użycia kodu. Oto jak można wykorzystać te konstrukcje do ustrukturyzowania projektu:

Moduły

  • Tworzenie modułu: Każdy plik TypeScript może być traktowany jako oddzielny moduł, jeśli zawiera jakiekolwiek importy lub eksporty.

// math.ts
export const dodaj = (a: number, b: number): number => a + b;
export const odejmij = (a: number, b: number): number => a - b;
  • Importowanie modułu: Możesz importować funkcje z modułu w innym pliku:
// app.ts
import { dodaj, odejmij } from './math';

console.log(dodaj(5, 3)); // 8
console.log(odejmij(5, 3)); // 2

Przestrzenie Nazw

Przestrzenie nazw (zwane też „internal modules”) są innym sposobem na grupowanie powiązanych funkcji, klas, interfejsów itp.

  • Definiowanie przestrzeni nazw:

namespace Matematyka {
    export const dodaj = (a: number, b: number): number => a + b;
    export const odejmij = (a: number, b: number): number => a - b;
}
  • Użycie przestrzeni nazw:
console.log(Matematyka.dodaj(5, 3)); // 8
console.log(Matematyka.odejmij(5, 3)); // 2

Użycie modułów i przestrzeni nazw pozwala na lepszą organizację kodu i uniknięcie kolizji nazw, co jest szczególnie ważne w dużych projektach.

Krok 7: Dekoratory i Metaprogramowanie

Dekoratory to specjalna deklaratywna składnia w TypeScript, która pozwala na dodawanie anotacji i metaprogramowania do klasy i jej członków. Dekoratory często używane są w frameworkach Angular i NestJS, gdzie upraszczają konfigurację i zachowanie komponentów.

Wprowadzenie do dekoratorów

  • Dekoratory klas: Dekoratory klas są stosowane bezpośrednio przed deklaracją klasy. Mogą być użyte do modyfikacji lub zamiany definicji klasy.

function Komponent(dekorator: any) {
    return function (target: Function) {
        // modyfikacje klasy
    }
}

@Komponent({selector: 'moj-komponent'})
class MojKomponent {
    // ...
}
  • Dekoratory metod: Dekoratory metod są stosowane bezpośrednio przed deklaracją metody klasy. Mogą służyć do modyfikacji, zamiany lub rozszerzania definicji metody.
function Zaloguj(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
        console.log(`Wywołano metodę: ${propertyKey}`);
        return originalMethod.apply(this, args);
    }
}

class MojKomponent {
    @Zaloguj
    mojaMetoda() {
        console.log('Wykonanie mojejMetody');
    }
}

Przykłady zastosowań

Dekoratory mogą być stosowane w różnych scenariuszach, takich jak:

  • Łączenie klas z dodatkowymi metadanymi,
  • Logowanie,
  • Autoryzacja,
  • Monitorowanie i zarządzanie wydajnością.

Metaprogramowanie z użyciem dekoratorów otwiera nowe możliwości w zakresie projektowania i organizacji kodu, pozwalając na pisanie bardziej modularnych i łatwych do zarządzania aplikacji.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 8: Zaawansowane Typowanie

TypeScript oferuje zaawansowane techniki typowania, które pozwalają na bardziej precyzyjne opisanie struktury danych i zachowań. Przyjrzymy się bliżej trzem zaawansowanym konceptom: typom warunkowym, mapowanym i narzędziowym.

Typy Warunkowe

Typy warunkowe pozwalają na tworzenie typów, które mogą dynamicznie zmieniać się w zależności od warunków. Są one podobne do instrukcji warunkowych w tradycyjnych językach programowania.

type MozliweTypy = T extends boolean ? 'To jest boolean' : T extends number ? 'To jest liczba' : 'Inny typ';

Mapowane Typy

Mapowane typy pozwalają na tworzenie nowych typów przez przetwarzanie właściwości istniejących typów. Umożliwiają one dynamiczne tworzenie typów na podstawie istniejących.

type TylkoDoOdczytu = {
    readonly [P in keyof T]: T[P];
};

Utility Types

TypeScript oferuje zestaw narzędziowych typów wbudowanych, które umożliwiają transformację typów w użyteczny sposób. Przykłady obejmują Partial<T>, Readonly<T>, Record<K, T> i wiele innych.

type Czesciowy = Partial; // Sprawia, że wszystkie właściwości typu T są opcjonalne

Zaawansowane typowanie jest potężnym narzędziem, które pozwala na tworzenie bardzo wyrafinowanych systemów typów, zapewniając przy tym bezpieczeństwo i elastyczność kodu.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 9: Narzędzia i Techniki Debugowania

Efektywne debugowanie jest niezbędne w procesie tworzenia oprogramowania. TypeScript, będąc nadzbiorem JavaScript, korzysta z wielu tych samych technik debugowania, co JavaScript, ale oferuje również dodatkowe narzędzia, które ułatwiają ten proces.

Używanie Source Maps

  1. Source Maps: TypeScript może generować pliki źródłowe (source maps), które mapują skompilowany kod JavaScript do oryginalnego kodu TypeScript. Umożliwia to debugowanie oryginalnego kodu TypeScript bezpośrednio w narzędziach deweloperskich przeglądarki lub IDE.

    Aby wygenerować source maps, możesz dodać flagę "sourceMap": true do pliku tsconfig.json:

{
    "compilerOptions": {
        "sourceMap": true
        // inne opcje...
    }
}

Debugowanie w Środowisku VS Code

Visual Studio Code, popularne IDE wspierające TypeScript, oferuje zaawansowane funkcje debugowania.

  1. Konfiguracja Debugowania: Możesz skonfigurować środowisko VS Code do debugowania TypeScript, tworząc plik konfiguracyjny debugowania (.vscode/launch.json).

  2. Ustawianie Punktów Przerwania: VS Code pozwala na ustawianie punktów przerwania bezpośrednio w kodzie TypeScript. Możesz następnie uruchomić debugger i śledzić wykonywanie kodu, przeglądać wartości zmiennych i stos wywołań.

Logowanie i Śledzenie

  1. Console.log i innych: Chociaż to podstawowe narzędzie, odpowiednio umieszczone instrukcje logowania mogą znacznie pomóc w śledzeniu przepływu programu i stanu danych.

  2. Śledzenie Stosu: Wykorzystanie console.trace() może ujawnić ścieżkę wywołań funkcji, co jest przydatne przy debugowaniu złożonych problemów związanych ze stosowaniem.

Techniki i narzędzia debugowania znacznie ułatwiają znajdowanie i rozwiązywanie problemów w kodzie, co przekłada się na szybszy rozwój i stabilniejsze aplikacje.

TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących

Krok 10: Najlepsze Praktyki

Pisanie kodu w TypeScript to nie tylko znajomość języka, ale także przestrzeganie pewnych zasad i konwencji, które sprawiają, że kod jest bardziej zrozumiały, łatwiejszy w utrzymaniu i mniej podatny na błędy.

  1. Używaj Explicit Typing: Zawsze określaj typy zmiennych, parametrów i wartości zwracanych. Pomaga to w zapewnieniu bezpieczeństwa typów i ułatwia zrozumienie kodu.

let isCompleted: boolean = false;
  1. Unikaj Typu any: Używanie any opuszcza system typów TypeScript i powinno być unikane, gdy to możliwe, na rzecz bardziej precyzyjnych typów.

  2. Używaj Interfejsów i Typów do Modelowania Struktur Danych: Definiuj struktury danych za pomocą interfejsów lub typów. To ułatwia zrozumienie, jak dane są używane i przekazywane w aplikacji.

interface User {
    name: string;
    age: number;
}
  1. Organizacja Kodu za Pomocą Modułów: Organizuj kod w modułach, to pomaga w utrzymaniu czystości kodu i ułatwia ponowne użycie kodu.

  2. Wykorzystaj Zalety Edytorów i Linterów: Korzystaj z edytorów kodu, takich jak Visual Studio Code, i konfiguruj linterów, takich jak ESLint, aby pomóc w utrzymaniu spójnego stylu kodu i wykrywaniu problemów.

  3. Pisz Testy Jednostkowe: Regularne testowanie jednostkowe to klucz do stabilnego oprogramowania. TypeScript ułatwia pisanie i utrzymanie testów dzięki lepszej strukturze i bezpieczeństwu typów.

Przestrzeganie tych praktyk nie tylko poprawi jakość Twojego kodu, ale także uczyni proces rozwoju bardziej efektywnym i przyjemnym.

Podsumowanie: W naszym podręczniku „TypeScript w 10 Prostych Krokach: Podręcznik dla Początkujących”, przybliżyliśmy Ci świat TypeScript, począwszy od podstaw, przez konfigurację środowiska, po zaawansowane koncepty i najlepsze praktyki. Pamiętaj, że nauka przez praktykę jest najskuteczniejsza, więc zachęcam do eksperymentowania z kodem i tworzenia własnych projektów w TypeScript.

Powodzenia w Twojej przygodzie z TypeScript!