Kilka lat temu straciłem cały weekend na buga, który TypeScript znalazłby w 3 sekundy. Pole userId w API zwracało raz string, raz number, w zależności od endpointa. JavaScript przyjmował oba bez słowa. Aplikacja sypała się w pięciu różnych miejscach, każde wyglądało inaczej, każde wskazywało na inny problem.

W poniedziałek rano zacząłem przepisywać projekt na TypeScript. Po dwóch tygodniach byłem przekonany. Dziś nie wyobrażam sobie powrotu.

Każdy projekt w mojej agencji jest w TypeScript. Frontend, backend, skrypty narzędziowe, wszystko. Ten post wyjaśnia, dlaczego, kiedy mimo wszystko warto użyć JS-a i jak płynnie przejść z jednego na drugi.

Co to jest TypeScript

TypeScript to JavaScript z systemem typów dolanym na wierzch. Kod TS się kompiluje (a właściwie transpiluje) do JS-a. W przeglądarce, na serwerze, w Node.js, ostatecznie i tak działa JS.

Inaczej niż w innych “nadbudowach” (CoffeeScript, Dart), TS nie próbuje zastąpić JavaScriptu. Tylko go ulepszyć. Każdy poprawny JavaScript jest poprawnym TypeScriptem. Wystarczy zmienić rozszerzenie pliku z .js na .ts, i już masz projekt TS.

Cała magia jest w fazie kompilacji. TS sprawdza Twoje typy, wyłapuje niezgodności, ostrzega przed błędami. Po kompilacji znika. Wynikowy kod to czysty JS.

To ważne, bo dużo ludzi myśli, że TS to “inny język” albo że “Node.js musi być specjalny, żeby uruchomić TS”. Nie. TS to narzędzie deweloperskie. JS to runtime.

TypeScript vs JavaScript w trzech zdaniach

JavaScript akceptuje wszystko i mówi “spróbujmy”. Problem widzisz w czasie działania, czasem na produkcji, czasem u klienta.

TypeScript odmawia uruchomienia kodu, który ma sprzeczności typów. Problem widzisz w IDE, zanim zapiszesz plik.

Cała różnica. Wszystko inne wynika z tej jednej rzeczy.

Dlaczego używam TS w agencji

Konkretnie. Bez “lepszej maintainability” i innych ogólników z LinkedIna.

Refaktor bez strachu. Zmieniam pole w jednym pliku, kompilator pokazuje 47 miejsc, gdzie też trzeba zmienić. W JS-ie znalazłbym 30, a 17 zostałoby na produkcję. Już raz mnie to drogo kosztowało.

IDE wie, co robi. W monorepo, gdzie Strapi generuje typy, które Next.js konsumuje, autouzupełnianie po stronie frontu wie, jakie pola ma model z backendu. Bez TS musiałbym pamiętać. Z TS-em pamiętać nie muszę.

Onboarding nowych ludzi. Kiedy junior wchodzi do projektu, typy są dokumentacją, która nie kłamie. Kiedy widzi funkcję processOrder(order: Order): Promise<Receipt>, wie, co dostaje, co dostarcza, co może się zepsuć. W JS-ie zaczynał od czytania 10 plików, żeby się zorientować.

Wyłapywanie całych klas błędów. Null albo undefined w niewłaściwym miejscu, literówki w nazwach pól, sprzeczność typu w API, zły kontrakt między frontem a backendem. TS łapie to wszystko, zanim wpiszesz git push.

Lepsze AI tooling. Cursor i Claude Code działają znacząco lepiej w TS-ie niż w JS-ie, bo widzą strukturę typów. Generują kod, który się od razu kompiluje. W JS-ie często generują kod, który “wygląda dobrze”, ale ma błędne nazwy pól.

Kiedy JS jest nadal lepszy

Nie wszystko musi być TypeScriptem. Nie jestem fanatykiem.

Skrypty jednorazowe. Piszesz “skrypt, który raz na trzy miesiące pobierze dane z API i wrzuci do CSV”? node script.js i koniec. Setup TS-a nie ma sensu dla 30 linijek kodu.

Małe prototypy. Próbujesz pomysł, sprawdzasz, czy ma sens, decydujesz, czy budować dalej. Nie chcesz walczyć z typami, chcesz zobaczyć, czy idea działa. JS jest szybszy do poznania.

Nauka nowej biblioteki. Czytasz tutorial, klepiesz przykłady, eksperymentujesz. Typy mogą przeszkadzać, kiedy nie wiesz jeszcze, jak biblioteka się zachowuje. Po nauczeniu się przerzucasz na TS.

Bash-replacement. Skrypt do automatyzacji deployu, do migracji plików, do generowania raportów. Zwykle JS, czasem nawet bez Node.js, tylko zx albo bash. Pisałem o tym podejściu w automatyzacji.

Wszystko inne idzie w TS. Każdy projekt klienta, każdy własny produkt, każde nietrywialne narzędzie wewnętrzne.

Realne wady TypeScriptu

Ludzie chwalący TS rzadko mówią, gdzie boli.

Setup overhead. Pierwszy raz konfigurujesz tsconfig.json, ESLint pod TS, build pipeline, paths, aliasy. Godzina-dwie zabawy. W JS-ie po prostu uruchamiasz node.

Czas kompilacji. W dużym monorepo z 400 plikami sprawdzanie typów może zająć 20 sekund. Hot reload zaczyna boleć. Są workaroundy (incremental builds, esbuild, swc), ale to dodatkowy koszt mentalny.

Type debugging hell. Kiedy TS pokazuje Ci błąd typu, który ma 200 linii i wygląda jak Type 'A & (B | C)' is not assignable to type 'D & (E | F<G>)', kosztuje to godzinę życia. Generic, conditional types, mapped types są mocne, ale jak coś się zepsuje, nie naprawisz tego intuicją.

Pokusa any. Kiedy nie umiesz zmusić TS-a do czegoś, dodajesz any i idziesz dalej. Jest legalne, ale niszczy wartość TS-a w danym miejscu. W zespole pojawia się “any-driven development” i traktujesz TS-a jak JS z dodatkowym ceremoniałem.

Krzywa nauki. TS nie jest trudny, ale wymaga czasu. Jeśli nie znasz JS-a porządnie, ucz się najpierw JS-a. TS nadbudowany na słabe fundamenty JS-a tylko ukrywa Twoje braki.

Częste mity, które warto rozbroić

“TypeScript jest wolniejszy.” Nieprawda. W produkcji to ten sam JS-owy bytecode. Wolniejsza jest tylko faza kompilacji, ale to faza developerska, nie produkcyjna.

“TS spowalnia development.” Krótkoterminowo tak, długoterminowo zdecydowanie nie. Pisanie pierwszych 100 linii w TS jest wolniejsze niż w JS. Pisanie 100. tysiąca linii i utrzymywanie ich jest dramatycznie szybsze.

“Trzeba znać TS, żeby pracować w nowoczesnym JS.” Półprawda. Trzeba znać TS, żeby dostać dobrą pracę w 2026 roku. Ale fundamenty to nadal JS. Najpierw async/await, this, prototypy, event loop. Potem TS.

“Małe projekty nie potrzebują TS.” Definicja “małego projektu” jest nieostra. Mój skrypt na 30 linijek nie potrzebuje. Mój blog z 5 plikami też nie. Ale każda apka, którą ktoś będzie utrzymywał za 6 miesięcy, potrzebuje. Dziś “mała”, jutro “produkcyjna”.

“Typy to tylko dokumentacja.” Typy to wymuszona dokumentacja. Różnica jak między komentarzem (który się dezaktualizuje) a deklaracją typu (która łamie build, jeśli nie pasuje do kodu).

Jak płynnie przejść z JS na TS

Migracja istniejącego projektu nie musi boleć. Mój przepis, który stosowałem w trzech projektach klienta:

  1. Zainstaluj TypeScript i dodaj tsconfig.json z ustawieniem "allowJs": true. To znaczy: “akceptuj zarówno .js jak i .ts”.
  2. Zmień rozszerzenie jednego pliku na .ts. Tego, który najmniej zależy od reszty (utility, helper).
  3. Uruchom kompilację. Zobacz, jakie błędy dostajesz. Napraw je albo dodaj // @ts-ignore z notatką “do naprawienia”.
  4. Powtarzaj plik po pliku. Zaczynaj od najprostszych (utility, types), kończ na komponentach z dużą logiką.
  5. Po zmigrowaniu wszystkich plików włącz strict mode ("strict": true). Dostaniesz nową falę błędów. Naprawiasz iteracyjnie.

Migracja projektu na 50 plików to 1-2 tygodnie pracy w tle, między innymi taskami. Nie próbuj zrobić tego w jeden dzień. Inkrementalnie jest zdrowiej.

Co czytać, jeśli chcesz wsiąść na poważnie

Po polsku jest niewiele dobrych materiałów do TS-a. Po angielsku:

  • Oficjalna dokumentacja (“TypeScript Handbook”). Najlepiej napisana dokumentacja języka, jaką znam. Nie pomijaj.
  • Type Challenges na GitHubie. Zadania, które uczą zaawansowanego systemu typów. Zacznij od poziomu easy.
  • “Effective TypeScript” Dana Vanderkama. Książka. 62 konkretne zasady, każda 2-3 strony. Najlepsza inwestycja w naukę TS-a, jaką możesz zrobić.

Nie kupuj kursów na Udemy. Nie potrzebujesz. Dokumentacja plus jeden mały projekt to wystarcza.

Od czego zacząć

Jeśli nie pisałeś jeszcze w TS:

  1. Naucz się JS-a porządnie. Bez tego TS Cię zje. Async, this, prototypy, event loop, modules. Pisałem o ścieżce nauki w jak zostać programistą bez studiów.
  2. Zrób mały projekt w TS od zera. Nie migruj istniejącego, zacznij świeży. Strona, API, cokolwiek. Poczuj, jak działa.
  3. Czytaj błędy kompilatora. Większość początkujących je ignoruje albo dodaje any. Te błędy uczą Cię TS-a lepiej niż jakikolwiek tutorial.
  4. Po miesiącu spróbuj zmigrować jeden mały projekt z JS-a. Zobaczysz różnicę przed i po.

W 2026 roku TypeScript jest standardem w komercyjnym JS-ie. Nie znaczy, że JS umiera. Znaczy, że jeśli pracujesz z kodem, który zostanie po Tobie dłużej niż weekend, prawdopodobnie powinien być w TS-ie.

JavaScripta pisałem długo. TypeScript od kilku lat. Nie wracam.