Menu

TypeScript vs JavaScript: główne różnice z przykładami

TypeScript to JavaScript z dodanym statycznym systemem typów, sprawdzanym przed uruchomieniem kodu. Porównaj oba języki obok siebie: składnię, błędy wyłapywane przez sprawdzanie typów, krok budowania, szybkość działania, próg wejścia i migrację projektu z JavaScriptu.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

TypeScript to JavaScript z dodanym na wierzchu statycznym systemem typów. Każdy program w JavaScripcie to poprawna składnia TypeScript. TypeScript dodaje adnotacje typów, kompilator, który sprawdza je przed uruchomieniem kodu, i krok budowania, który z powrotem je usuwa. W czasie wykonania jest tylko JavaScript, więc cała różnica polega na tym, czego dowiadujesz się przed wdrożeniem.

W JavaScripcie ta sama funkcja to ten kod bez type Product = ..., : Product[] i : number. Typy dodają informacje dla kompilatora i edytora, ale nie zmieniają tego, co robi program.

TypeScript vs JavaScript w skrócie

JavaScriptTypeScript
System typówDynamiczny: typy należą do wartości i są znane dopiero w czasie wykonaniaStatyczny: typy są deklarowane albo wnioskowane i sprawdzane w czasie kompilacji
Kiedy pojawiają się błędy typówGdy linia się wykonuje (undefined, NaN, TypeError)W edytorze podczas pisania i przy kompilacji
Gdzie działaBezpośrednio w przeglądarkach, Node.js, Deno, BunW tych samych miejscach, po usunięciu typów
Krok budowaniaNiepotrzebnytsc albo bundler, albo środowisko, które samo usuwa typy
Pliki.js, .mjs, .cjs.ts, .mts, .cts, .tsx oraz deklaracje typów .d.ts
Szybkość działaniaPunkt odniesieniaIdentyczna: wyjście to JavaScript
Obsługa w edytorzePodpowiedzi z wywnioskowanych typów i typów bibliotek, które mogą być niekompletnePodpowiedzi, zmiana nazw i "find all references" z zadeklarowanych typów
Próg wejściaNiższyJavaScript plus system typów
StandardECMAScript, tworzony przez TC39Projekt open source Microsoftu, który podąża za ECMAScript

Ten sam kod w obu językach

Oto funkcja w JavaScripcie. Nic w niej nie mówi, jak musi wyglądać user:

function greeting(user) {
    return `Hello, ${user.firstName} ${user.lastName}`;
}

greeting({ firstname: "Ada", lastName: "Lovelace" });
// "Hello, undefined Lovelace", no error anywhere

Wersja w TypeScript raz opisuje kształt, a literówka jest zgłaszana przed uruchomieniem kodu:

interface User {
    firstName: string;
    lastName: string;
}

function greeting(user: User): string {
    return `Hello, ${user.firstName} ${user.lastName}`;
}

greeting({ firstname: "Ada", lastName: "Lovelace" });
// error TS2561: Object literal may only specify known properties,
// but 'firstname' does not exist in type 'User'. Did you mean to write 'firstName'?

Adnotacje to cała różnica w składni. TypeScript dodaje też kilka własnych deklaracji (interface, type, enum, generyki takie jak Array<string>, modyfikatory dostępu takie jak private), ale instrukcje, operatory i wbudowane obiekty pochodzą z JavaScriptu.

Co wyłapuje TypeScript, a czego nie wyłapuje JavaScript

JavaScript po cichu konwertuje typy. Ten błąd jest częsty przy wartościach z pól formularzy, które zawsze są stringami. Uruchom kod, żeby zobaczyć, co mówi kompilator:

index.ts(7,17): error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
  Type 'string' is not assignable to type 'number'.

W JavaScripcie to się wykonuje i wypisuje 010205, bo 0 + "10" to łączenie stringów. TypeScript odmawia kompilacji, dopóki stringi nie zostaną przekonwertowane, na przykład przez fromForm.map(Number).

Druga duża kategoria to wartości, których może brakować. Array.prototype.find zwraca undefined, gdy nic nie pasuje, a TypeScript zmusza cię do obsłużenia tego:

index.ts(8,13): error TS18048: 'user' is possibly 'undefined'.

Wersja w zwykłym JavaScripcie wywraca się w czasie wykonania z TypeError: Cannot read properties of undefined (reading 'name'). Poprawka w TypeScript to obsłużenie przypadku, który wskazał kompilator:

Wynik:

GRACE
no user with id 3

Czego TypeScript nie wyłapie: błędów logicznych (zły wzór ma poprawny typ) i niczego, co dotyczy danych wchodzących do programu w czasie wykonania. Odpowiedź API otypowana jako User jest tak poprawna jak serwer, który ją wysłał, bo po uruchomieniu kodu typów już nie ma. Takie dane sprawdzaj kodem wykonywanym w czasie działania programu.

Biblioteki JavaScriptu w TypeScript

Każdy pakiet npm działa w TypeScript, bo wyjście i tak jest JavaScriptem. Typy pakietu pochodzą z jednego z trzech miejsc:

  • Pakiet ma własne pliki .d.ts. Większość aktywnie rozwijanych pakietów je ma i nie instalujesz niczego więcej.
  • Osobny pakiet @types ze społecznościowego projektu DefinitelyTyped: npm install --save-dev @types/lodash dodaje typy dla lodash.
  • Znikąd. Wtedy przy włączonym strict sam import jest błędem:
error TS7016: Could not find a declaration file for module 'lodash'. '/project/node_modules/lodash/lodash.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/lodash` if it exists or add a new declaration (.d.ts) file containing `declare module 'lodash';`

Rozwiązaniem jest instalacja pakietu @types, jeśli istnieje, albo samodzielne opisanie modułu w pliku .d.ts. Jak to zrobić, pokazuje strona o plikach deklaracji.

Krok budowania

Przeglądarki i Node.js nie sprawdzają typów, więc TypeScript potrzebuje kroku między twoim kodem źródłowym a kodem, który się wykonuje. Są trzy popularne konfiguracje:

  • tsc kompiluje wszystko. Sprawdza typy i zapisuje pliki .js, zwykle do folderu dist. Proste i standardowe w bibliotekach.
  • Bundler albo serwer deweloperski usuwa typy, a tsc --noEmit je sprawdza. Vite i esbuild usuwają typy bez sprawdzania, co utrzymuje szybkie przeładowania, a moduł sprawdzania typów uruchamiają edytor i krok w CI.
  • Środowisko uruchomieniowe usuwa typy. Aktualne wersje Node.js, Deno i Bun uruchamiają pliki .ts bezpośrednio. Żadne z nich nie sprawdza typów podczas działania, więc błędy typów nadal znajdujesz przez tsc --noEmit (albo deno check).

JavaScript nie potrzebuje niczego z tego i to jego największa praktyczna przewaga przy małych skryptach. Koszt kroku TypeScript to głównie konfiguracja, tsconfig.json i zależność deweloperska typescript, oraz czas kompilacji. Natywny kompilator TypeScript 7 skrócił ten czas w dużych projektach mniej więcej dziesięciokrotnie.

Próg wejścia

Wszystko, co wiesz o JavaScripcie, nadal obowiązuje, bo TypeScript w czasie wykonania to JavaScript. Nowy materiał to system typów, a ten ma kilka warstw:

  1. Adnotacje zmiennych, parametrów i wartości zwracanych (: string, : number[]).
  2. Typy obiektów z interface i type, właściwości opcjonalne, unie takie jak string | number.
  3. Zawężanie: sprawdzanie wartości przez typeof, in albo ===, żeby kompilator wiedział, z którym przypadkiem masz do czynienia.
  4. Generyki, typy narzędziowe takie jak Partial<T> i Pick<T, K> oraz zaawansowane typy dla autorów bibliotek.

Pierwsze dwie warstwy wystarczają w większości kodu aplikacji. Dużą część typów kompilator wnioskuje sam, więc sporo kodu w TypeScript wygląda jak JavaScript z adnotacjami tylko w sygnaturach funkcji.

Kiedy wybrać TypeScript, a kiedy JavaScript

Czy TypeScript jest lepszy od JavaScriptu? W kodzie, który utrzymuje kilka osób albo który żyje latami, zwykle tak, i branża poszła w tę stronę: według liczby miesięcznych kontrybutorów podawanej przez GitHub TypeScript w sierpniu 2025 wyprzedził zarówno JavaScript, jak i Pythona i stał się najczęściej używanym językiem na GitHubie. Przy małych skryptach zwykły JavaScript jest często lepszym narzędziem.

Wybierz TypeScript, gdy:

  • Nad kodem pracuje więcej niż jedna osoba albo będzie on utrzymywany miesiącami lub latami.
  • Baza kodu jest na tyle duża, że nie da się pamiętać sygnatury każdej funkcji.
  • Często refaktoryzujesz: zmiana nazwy właściwości aktualizuje każde jej użycie, a kompilator wymienia wszystko, co zostało.
  • Publikujesz bibliotekę: pliki .d.ts dają jej użytkownikom podpowiedzi i sprawdzanie.
  • Wymaga tego framework. Aplikacje Angular pisze się w TypeScript, Next.js i Astro domyślnie tworzą nowe projekty w TypeScript, a szablony Vite dla React, Vue i Svelte mają każdy wariant w TypeScript.

Wybierz JavaScript, gdy:

  • Program to krótki skrypt, jednorazowy eksperyment albo fragment kodu w konsoli przeglądarki.
  • Uczysz się programowania od zera i chcesz mieć naraz mniej pojęć.
  • Nie ma kroku budowania i nie chcesz go mieć. Nawet wtedy // @ts-check z JSDoc daje trochę sprawdzania w zwykłym pliku .js.

Migracja projektu z JavaScriptu do TypeScript

Migracja nie musi odbyć się naraz. Kompilator przyjmuje JavaScript obok TypeScript:

{
    "compilerOptions": {
        "allowJs": true,
        "checkJs": false,
        "outDir": "dist",
        "rootDir": "src"
    },
    "include": ["src"]
}

Z allowJs pliki .js się kompilują i mogą importować z plików .ts, i odwrotnie. Potem przechodź stopniowo:

  1. Zmień nazwę jednego pliku z .js na .ts i popraw błędy, które kompilator w nim zgłasza.
  2. Zacznij od liści (modułów narzędziowych z niewieloma importami), a potem idź w głąb.
  3. Włącz checkJs albo dodaj // @ts-check na początku pojedynczych plików .js, żeby sprawdzać typy w plikach, którym jeszcze nie zmieniono nazwy.

W sprawdzanych plikach JavaScript typy dostarczają komentarze JSDoc:

// @ts-check

/**
 * @param {number} price
 * @param {number} qty
 * @returns {number}
 */
function lineTotal(price, qty) {
    return price * qty;
}

lineTotal("3", 2);
// error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Niektóre zespoły na tym poprzestają: pliki JavaScript z typami w JSDoc, sprawdzane przez tsc, bez kroku budowania dla samego kodu. Inne przechodzą całkowicie na .ts. Jeśli włączasz strict w istniejącym projekcie, na początku spodziewaj się wielu błędów. Strona o trybie strict wymienia, co sprawdza każda flaga, więc możesz włączać je po jednej.

Najczęściej zadawane pytania

Jaka jest główna różnica między TypeScript a JavaScriptem?

TypeScript dodaje do JavaScriptu statyczne typy. Opisujesz, czym jest każda wartość (name: string, items: Item[]), a kompilator TypeScript zgłasza pomyłki, zanim kod się uruchomi. JavaScript niczego nie sprawdza z wyprzedzeniem: zły typ wychodzi na jaw dopiero, gdy wykona się dana linia, często jako undefined albo TypeError.

Czy TypeScript jest lepszy od JavaScriptu?

W większości projektów, które utrzymuje więcej niż jedna osoba albo które żyją dłużej niż kilka tygodni, tak: typy wyłapują całe klasy błędów, sprawiają, że refaktoryzacja jest bezpieczna, i napędzają podpowiedzi w edytorze. Przy krótkim skrypcie, szybkim prototypie albo ćwiczeniu do nauki zwykły JavaScript pozwala szybciej zacząć i nie wymaga konfiguracji budowania.

Czy TypeScript jest szybszy od JavaScriptu?

Nie, ale też nie jest wolniejszy. TypeScript kompiluje się do JavaScriptu, a typy są usuwane, więc wykonywany kod to ten sam JavaScript, jaki można napisać ręcznie. Jedyny dodatkowy koszt to czas kompilacji podczas pracy nad kodem.

Czego uczyć się najpierw: JavaScriptu czy TypeScriptu?

Podstaw JavaScriptu najpierw albo razem z TypeScriptem. Całe zachowanie w czasie wykonania (zmienne, funkcje, obiekty, tablice, promise'y) to JavaScript, a TypeScript tylko je opisuje. Gdy potrafisz pisać małe programy w JavaScripcie, dodanie typów to krótki krok.

Czy można używać TypeScriptu i JavaScriptu w jednym projekcie?

Tak. Ustaw "allowJs": true w tsconfig.json, a kompilator przyjmie pliki .js obok plików .ts. Dodaj "checkJs": true (albo komentarz // @ts-check w każdym pliku), żeby sprawdzać typy także w plikach JavaScript, z typami z komentarzy JSDoc. Tak zwykle migruje się projekt plik po pliku.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ