Dataczwartek, 13 sierpnia 2026 Czas18:00:40
← Aplikacje webowe

Lekcja 6. TypeScript — podstawy języka: typy, interfejsy i klasy

Średni

Po co się tego uczymy?

Angular pisze się w TypeScript, więc zanim zbudujesz cokolwiek poważniejszego niż jeden przycisk, musisz poznać ten język. Dobra wiadomość: jeśli znasz C#, TypeScript będzie Ci się wydawał bardzo znajomy — silne typowanie, klasy, interfejsy — to te same koncepcje, które poznałeś w dziale programowania obiektowego, tylko zapisane trochę inną składnią i finalnie kompilowane do zwykłego JavaScriptu.

Teoria

Czym jest TypeScript? To język stworzony przez Microsoft jako NADZBIÓR JavaScriptu — każdy poprawny kod JavaScript jest jednocześnie poprawnym kodem TypeScript, ale TypeScript DODAJE do niego system typów (podobny do tego, co znasz z C#) i inne udogodnienia (interfejsy, klasy w nowoczesnym stylu, generyki). Przeglądarki NIE rozumieją TypeScriptu bezpośrednio — kod .ts jest KOMPILOWANY (a właściwie "transpilowany") do zwykłego JavaScriptu, zanim trafi do przeglądarki. Ten proces dzieje się automatycznie w tle, gdy uruchamiasz projekt Angular.

Dlaczego typy są tak ważne? W zwykłym JavaScript zmienna może w jednej linijce być liczbą, a w następnej stringiem — co prowadzi do trudnych do wyśledzenia błędów. TypeScript pozwala zadeklarować, JAKIEGO typu jest dana zmienna, i zgłasza błąd KOMPILACJI (czyli ZANIM program się uruchomi), jeśli spróbujesz przypisać niewłaściwą wartość — dokładnie ta sama korzyść, którą daje silne typowanie w C#.

Konstrukcja TypeScript Odpowiednik w C# Przykład
let x: number = 5; int x = 5; (choć TS ma tylko jeden typ liczbowy) liczby całkowite i zmiennoprzecinkowe to w TS TEN SAM typ number
let s: string = "cześć"; string s = "cześć"; teksty
let czyGotowe: boolean = true; bool czyGotowe = true; wartości logiczne
let lista: number[] = [1, 2, 3]; List<int> lista = new() {1,2,3}; tablice/listy
interface Produkt { nazwa: string; cena: number; } podobne do klasy z samymi właściwościami (bez logiki) opis KSZTAŁTU obiektu, bez implementacji
class Produkt { ... } class Produkt { ... } klasa z polami I metodami — bardzo podobna składnia do C#
function suma(a: number, b: number): number { ... } int Suma(int a, int b) { ... } funkcja z typowanymi parametrami i typem zwracanym

Interfejsy — opis "kształtu" danych. W TypeScript interfejs (interface) opisuje, JAKIE właściwości musi mieć obiekt, bez definiowania żadnej logiki — bardzo przydatne do opisania struktury danych przychodzących z backendu (np. odpowiedzi JSON z Web API C#, pełne omówienie w lekcji 12). To trochę jak model danych z C# (klasa z samymi właściwościami), tylko bez potrzeby tworzenia instancji przez new.

Typy opcjonalne i null. Znak zapytania po nazwie właściwości (cena?: number) oznacza, że ta właściwość jest OPCJONALNA (może nie istnieć w ogóle) — podobna koncepcja do double? w C#, choć techniczne działanie różni się w szczegółach.

Konfiguracja kompilatora — plik tsconfig.json. Określa, jak ściśle TypeScript sprawdza typy, do jakiej wersji JavaScriptu kompiluje kod, i inne ustawienia — w projektach Angular jest generowany automatycznie przez Angular CLI, zwykle nie trzeba go ręcznie modyfikować na początku nauki.

Schemat

Plik .ts (TypeScript, pisany przez programistę)
        │
        │  kompilator TypeScript (tsc), uruchamiany automatycznie
        │  przez Angular CLI (ng serve / ng build)
        ▼
Plik .js (zwykły JavaScript, zrozumiały dla przeglądarki)
        │
        ▼
Wykonanie w przeglądarce użytkownika

Sprawdzanie typów - PRZED uruchomieniem:
let cena: number = "sto złotych";   ← BŁĄD KOMPILACJI, wykryty od razu
                                       (string przypisany do number)

interface Produkt {              class Produkt {                (dla porównania: C#)
  nazwa: string;                   public string Nazwa {get;set;}
  cena: number;                    public double Cena {get;set;}
}                                }
(tylko OPIS kształtu danych)     (klasa z polami i metodami)

Przykład z życia

Formularz rejestracji w aplikacji Angular oczekuje, że pole "wiek" będzie liczbą — dzięki TypeScript, próba przypisania do niego tekstu (np. przez błąd w kodzie, nie przez użytkownika — to inny temat, walidacja formularzy) zostanie wykryta ZANIM aplikacja w ogóle zostanie uruchomiona, a nie dopiero w trakcie działania u klienta, gdzie błąd byłby dużo trudniejszy do namierzenia.

modele.ts

// modele.ts - interfejsy opisujące kształt danych
export interface Produkt {
  id: number;
  nazwa: string;
  cena: number;
  dostepny?: boolean;   // znak zapytania = pole opcjonalne
}

// Funkcja z typowanymi parametrami i typem zwracanym
function obliczRabat(cena: number, procent: number): number {
  return cena - (cena * procent / 100);
}

const cenaPoRabacie = obliczRabat(100, 20);   // 80
console.log(cenaPoRabacie);

klasa.ts

// klasa.ts - klasa TypeScript (podobna do klasy C#)
export class KontoBankowe {
  private saldo: number;

  constructor(saldoPoczatkowe: number) {
    this.saldo = saldoPoczatkowe;
  }

  wplac(kwota: number): void {
    this.saldo += kwota;
  }

  wyplac(kwota: number): boolean {
    if (kwota > this.saldo) {
      return false;   // niewystarczające środki
    }
    this.saldo -= kwota;
    return true;
  }

  pobierzSaldo(): number {
    return this.saldo;
  }
}

// Użycie:
const konto = new KontoBankowe(100);
konto.wplac(50);
const udaloSie = konto.wyplac(30);
console.log(konto.pobierzSaldo());   // 120

Komentarz i wyjaśnienie kodu

Zwróć uwagę na PRAWIE identyczną strukturę klasy KontoBankowe do tego, co pisałbyś w C#: pole prywatne (private saldo: number), konstruktor (constructor(...) zamiast nazwy klasy jak w C#), metody z typowanymi parametrami i typem zwracanym. Główne różnice składniowe: typ podaje się PO dwukropku (saldo: number, a nie number saldo), słowo kluczowe constructor zamiast powtórzenia nazwy klasy, oraz void jako typ zwracany dla metod niczego nie zwracających — dokładnie jak w C#.

export przed interface/class pozwala UŻYĆ tego elementu w INNYM pliku TypeScript przez import { Produkt } from './modele'; — to bezpośredni odpowiednik public na poziomie klasy w C#, tylko zorganizowany wokół PLIKÓW (moduły ES) zamiast przestrzeni nazw.

Ćwiczenie samodzielne

Utwórz plik .ts (może być poza projektem Angular, np. w prostym projekcie Node.js albo online w playground TypeScript na stronie typescriptlang.org) z interfejsem opisującym dowolny obiekt (np. Ksiazka z tytułem, autorem, rokiem wydania) i funkcją operującą na tablicy takich obiektów (np. filtrowanie książek wydanych po określonym roku).

Zadania do pracy własnej

  1. Zdefiniuj interfejs Uczen (imię, nazwisko, średnia ocen) i napisz funkcję czyNaStypendium(uczen: Uczen): boolean zwracającą true, jeśli średnia jest większa niż 4.75.

  2. Napisz klasę Prostokat z polami szerokosc i wysokosc (typu number), konstruktorem przyjmującym obie wartości, oraz metodami pole(): number i obwod(): number — przetestuj ją tworząc kilka instancji z różnymi wymiarami.

  3. Wykorzystaj TypeScriptowe GENERYKI (składnia bardzo podobna do generyków C#: class Stos<T> { ... }) do zaimplementowania prostej struktury danych "stos" (LIFO — Last In, First Out) z metodami dodaj(element: T): void, zdejmij(): T | undefined i czyPusty(): boolean — przetestuj ją zarówno na stosie liczb, jak i stosie stringów, korzystając z JEDNEJ, uniwersalnej klasy.

Typowe błędy

Ignorowanie błędów typów zgłaszanych przez kompilator ("przecież i tak działa w przeglądarce") — błędy typów w TypeScript są sygnałem, że kod praktycznie na pewno ma ukrytą pomyłkę logiczną, nawet jeśli akurat nie ujawnia się w bieżącym teście.

Nadużywanie typu any (oznaczającego "dowolny typ, bez sprawdzania") jako "łatwego wyjścia" z błędu kompilacji — to rezygnacja z GŁÓWNEJ zalety TypeScriptu; lepiej poświęcić chwilę na znalezienie poprawnego typu.

Mylenie interfejsu (interface, tylko opis kształtu danych) z klasą (class, pełna implementacja z metodami) — interfejsu NIE MOŻNA utworzyć przez new, bo nie zawiera żadnej logiki, tylko strukturę.

Nawiązanie do egzaminu zawodowego

To realizacja INF.04.7.2 (frameworki i języki aplikacji webowych, gdzie TypeScript jest nierozerwalnie związany z Angularem) — solidna znajomość podstaw TypeScript jest WARUNKIEM zrozumienia wszystkich kolejnych lekcji o Angularze (8-10), bo cała logika komponentów jest pisana właśnie w tym języku. Kolejna lekcja przechodzi do stylowania interfejsu — biblioteki Bootstrap.