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
| JavaScript | TypeScript | |
|---|---|---|
| System typów | Dynamiczny: typy należą do wartości i są znane dopiero w czasie wykonania | Statyczny: typy są deklarowane albo wnioskowane i sprawdzane w czasie kompilacji |
| Kiedy pojawiają się błędy typów | Gdy linia się wykonuje (undefined, NaN, TypeError) | W edytorze podczas pisania i przy kompilacji |
| Gdzie działa | Bezpośrednio w przeglądarkach, Node.js, Deno, Bun | W tych samych miejscach, po usunięciu typów |
| Krok budowania | Niepotrzebny | tsc 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łania | Punkt odniesienia | Identyczna: wyjście to JavaScript |
| Obsługa w edytorze | Podpowiedzi z wywnioskowanych typów i typów bibliotek, które mogą być niekompletne | Podpowiedzi, zmiana nazw i "find all references" z zadeklarowanych typów |
| Próg wejścia | Niższy | JavaScript plus system typów |
| Standard | ECMAScript, tworzony przez TC39 | Projekt 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
@typesze społecznościowego projektu DefinitelyTyped:npm install --save-dev @types/lodashdodaje typy dlalodash. - Znikąd. Wtedy przy włączonym
strictsam 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:
tsckompiluje wszystko. Sprawdza typy i zapisuje pliki.js, zwykle do folderudist. Proste i standardowe w bibliotekach.- Bundler albo serwer deweloperski usuwa typy, a
tsc --noEmitje 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
.tsbezpośrednio. Żadne z nich nie sprawdza typów podczas działania, więc błędy typów nadal znajdujesz przeztsc --noEmit(albodeno 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:
- Adnotacje zmiennych, parametrów i wartości zwracanych (
: string,: number[]). - Typy obiektów z
interfaceitype, właściwości opcjonalne, unie takie jakstring | number. - Zawężanie: sprawdzanie wartości przez
typeof,inalbo===, żeby kompilator wiedział, z którym przypadkiem masz do czynienia. - Generyki, typy narzędziowe takie jak
Partial<T>iPick<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.tsdają 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-checkz 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:
- Zmień nazwę jednego pliku z
.jsna.tsi popraw błędy, które kompilator w nim zgłasza. - Zacznij od liści (modułów narzędziowych z niewieloma importami), a potem idź w głąb.
- Włącz
checkJsalbo dodaj// @ts-checkna 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.