Jak powstał Destinations (cz. 2): z JavaScriptu na TypeScript

12.10.2026 · 3 min czytania

W części 1 opowiedziałem, że pierwszą wersję Destinations napisałem świadomie w czystym JavaScripcie — żeby szybciej dowieźć działającą aplikację. Teraz czas na drugą część tej historii: jak i dlaczego spłaciłem ten dług, przepisując projekt na TypeScript.

Co mnie zaczęło uwierać w JS#

Dopóki projekt był mały, JS wystarczał. Problem pojawił się, gdy destynacje miały krążyć po całej aplikacji: z bazy do generatora testów, do tabel do druku, do panelu. W każdym z tych miejsc musiałem pamiętać, jak dokładnie wygląda obiekt destynacji — czy pole to abbreviation czy abbr, expansion czy może name. Skala projektu nie jest ogromna, ale jej przyszły rozrost mógłby te problemy pogłębić. No i była to świetna okazja, żeby nauczyć się TS.

Do tego dochodził brak podpowiedzi edytora (teraz może pamiętam nazwy pól w obiekcie, ale w przyszłości musiałbym co chwilę wracać do danych, żeby sprawdzić nazwy tych pól). No i strach przed refaktorem — zmiana nazwy jednego pola oznaczałaby ręczne polowanie na wszystkie użycia, z nadzieją, że żadnego nie przeoczę.

Decyzja: migracja, a nie przepisywanie od zera#

Nie zaczynałem projektu na nowo. Przepisanie wszystkiego od zera to najprostsza droga do porzucenia działającej aplikacji. Zamiast tego zrobiłem to stopniowo: dodałem konfigurację TypeScriptu, zmieniałem pliki .jsx na .tsx po kolei i naprawiałem błędy, które TS mi po drodze wyrzucał.

Najpierw domena#

Zacząłem od najważniejszego: otypowania samej destynacji. Zamiast „obiektu, który mam nadzieję, że ma odpowiednie pola”, dostałem jawny kontrakt:

export interface Destination {
  abbreviation: string; // kod, np. "STN"
  expansion: string; // rozwinięcie, np. "Londyn Stansted"
  country: string; // np. "Wielka Brytania"
  zone: string; // np. "Non-Schengen"
}

Co TypeScript złapał od razu#

Gdy tylko otypowałem destynację, mój wcześniejszy błąd z literówką przestał być cichy:

// Wcześniej (JS): milczenie, pusta komórka w teście
<td>{destination.expantion}</td>

// Po otypowaniu (TS) — błąd od razu w edytorze:
// Property 'expantion' does not exist on type 'Destination'.
// Did you mean 'expansion'?

Czego się nauczyłem#

W części 3 wchodzimy głębiej: skąd biorą się destynacje i jak schowałem panel szkoleniowca za logowaniem — czyli Firebase, baza i uwierzytelnianie.

Więcej z tej serii

  1. 1.Jak powstał Destinations (cz. 1): pomysł, domena i stack
  2. 2.Jak powstał Destinations (cz. 2): z JavaScriptu na TypeScript
  3. 3.Jak powstał Destinations (cz. 3): Firebase — baza i logowanie
  4. 4.Jak powstał Destinations (cz. 4): chronione trasy w React Router
  5. 5.Jak powstał Destinations (cz. 5): generatory testów i CSS do druku