Pliku TypeScript nie da się uruchomić w takiej postaci, bo przeglądarki i silniki JavaScript nie rozumieją adnotacji typów. Coś musi najpierw usunąć typy. Tym czymś jest albo kompilator TypeScript (tsc), który przy okazji sprawdza typy, albo szybsze narzędzie, które tylko je wycina. Najszybszy sposób na uruchomienie kodu z tej strony to przycisk Run:
Wynik:
[x] Install TypeScript
[ ] Run a .ts file
Każdy uruchamialny blok w tej dokumentacji działa tak samo: kod jest sprawdzany przez TypeScript 7 z włączonym strict i uruchamia się tylko wtedy, gdy nie ma błędów typów. Do dłuższych eksperymentów służy edytor online TypeScript, ten sam edytor na osobnej stronie. Reszta tej strony dotyczy uruchamiania plików .ts na własnym komputerze.
Opcje w skrócie
| Polecenie | Sprawdza typy | Wymaga kroku budowania | Obsługuje enum, namespace, parameter properties |
|---|---|---|---|
npx tsc, potem node dist/index.js | Tak | Tak | Tak |
node index.ts (Node.js 22.18+, 23.6+) | Nie | Nie | Nie |
npx tsx index.ts | Nie | Nie | Tak |
npx ts-node index.ts | Tak | Nie | Tak, ale nie z TypeScript 7 |
deno run index.ts | Nie (robi to deno check) | Nie | Tak |
bun index.ts | Nie | Nie | Tak |
Najbardziej zaskakuje pierwsza kolumna: większość szybkich opcji uruchamia kod, w którym są błędy typów. Typowy projekt uruchamia kod jednym z nich, a osobno, w edytorze i w CI, puszcza tsc --noEmit, żeby wyłapać błędy.
Kompilacja przez tsc, potem uruchomienie w Node
To podejście działa wszędzie i sprawdza wszystko. Z TypeScriptem zainstalowanym w projekcie i tsconfig.json, który ustawia "rootDir": "./src" i "outDir": "./dist":
npx tsc
node dist/index.js
tsc sprawdza typy we wszystkich plikach, a potem zapisuje pliki .js w dist. Dla pojedynczego pliku bez projektu przekaż nazwę pliku. Wtedy używane są domyślne opcje, a index.js powstaje obok index.ts:
npx tsc index.ts
node index.js
(Jeśli w folderze jest tsconfig.json, tsc odrzuca nazwy plików z error TS5112; uruchom samo npx tsc albo dodaj --ignoreConfig.)
Domyślnie tsc zapisuje JavaScript nawet wtedy, gdy są błędy typów, więc node może uruchomić program, który nie przeszedł sprawdzenia. Dodaj "noEmitOnError": true do konfiguracji, żeby temu zapobiec, albo połącz polecenia w skrypcie, tak by drugi krok uruchamiał się tylko po udanym pierwszym:
{
"scripts": {
"build": "tsc",
"start": "tsc && node dist/index.js"
}
}
Podczas pracy npx tsc --watch kompiluje ponownie przy każdym zapisie.
Uruchamianie TypeScript bezpośrednio w Node.js
Aktualne Node.js samo uruchamia pliki .ts:
node index.ts
Node wycina adnotacje typów, zastępując je białymi znakami, żeby numery linii w stack trace'ach nadal się zgadzały, i uruchamia to, co zostaje. Jest to włączone domyślnie od Node.js 23.6.0 i 22.18.0, nie wypisuje ostrzeżenia od 24.3.0 i 22.18.0, a jako stabilne zostało oznaczone w Node.js 24.12.0 i 25.2.0. Wcześniejsze wersje, które mają tę funkcję (od 22.6 do 22.17 oraz od 23.0 do 23.5), potrzebują flagi: node --experimental-strip-types index.ts.
Wiążą się z tym cztery zasady:
- Brak sprawdzania typów. Plik z
const age: number = "forty"się uruchamia i wypisujeforty. - Tylko składnia, którą da się usunąć. Wszystko, co musi stać się kodem JavaScript, a nie zniknąć, zostaje odrzucone:
enum, blokinamespacez kodem wykonywalnym, parameter properties w konstruktorze, takie jakconstructor(private name: string), i aliasyimport x = require(). Node zatrzymuje się zSyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode. tsconfig.jsonjest ignorowany. Opcje takie jakpathsczytargetnie mają wpływu.- Importy wymagają prawdziwych nazw plików. Pisz
import { add } from "./math.ts", z rozszerzeniem, i oznaczaj importy samych typów przeztype:import { add, type Pair } from "./math.ts". BeztypeNode szuka eksportu wykonywalnego o nazwiePairi kończy się błędemSyntaxError: The requested module './math.ts' does not provide an export named 'Pair'.
Dwie opcje kompilatora sprawiają, że tsc egzekwuje te same zasady, więc edytor ostrzega cię, zanim zrobi to Node: "erasableSyntaxOnly": true zgłasza error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. przy enum, a "verbatimModuleSyntax": true wymaga słowa type przy importach samych typów. Aby dalej pisać rozszerzenia .ts w importach i nadal kompilować przez tsc, dodaj "rewriteRelativeImportExtensions": true, co w wyniku zamienia ./math.ts na ./math.js.
Node.js 24 ma też --experimental-transform-types, które generuje kod dla enumów i parameter properties zamiast je odrzucać. Wypisuje ExperimentalWarning, a Node.js 26 usunął tę flagę, więc nie opieraj się na niej.
Ten blok używa dwóch funkcji, które node index.ts odrzuca. Tutaj działa, bo edytor kompiluje go kompilatorem TypeScript, który generuje JavaScript dla obu:
Wersja tego samego kodu, którą da się wyczyścić z typów, używa obiektu const i zwykłego pola, co Node może uruchomić bez zmian:
tsx
tsx uruchamia plik TypeScript w jednym kroku, bez konfiguracji i bez ograniczeń składni:
npm install --save-dev tsx
npx tsx index.ts
npx tsx watch index.ts # rerun on every change
Przekształca kod przez esbuild, więc enumy, namespace'y i parameter properties działają, a importy bez rozszerzeń są rozwiązywane tak jak w bundlerze. Podobnie jak type stripping w Node, nie sprawdza typów. To popularny wybór dla skryptów, serwerów deweloperskich i testów na wersjach Node.js sprzed type strippingu albo gdy kod używa składni, którą Node odrzuca.
ts-node
ts-node przez lata był standardowym sposobem uruchamiania TypeScriptu w Node.js i nadal używa go wiele tutoriali i starszych projektów (npx ts-node index.ts, node -r ts-node/register). Domyślnie sprawdza typy, korzystając z JavaScriptowego API kompilatora TypeScript.
Tego właśnie API TypeScript 7 nie dostarcza: jego kompilator to natywny program, a pakiet typescript 7 nie udostępnia JavaScriptowi żadnego API kompilatora. Z zainstalowanym TypeScript 7 ts-node wywala się, zanim cokolwiek uruchomi:
TypeError: Cannot read properties of undefined (reading 'fileExists')
at readConfig (/project/node_modules/ts-node/dist/configuration.js:91:33)
Najnowsze wydanie ts-node, 10.9.2, pochodzi z grudnia 2023. W nowym kodzie używaj tsx lub node index.ts. Istniejąca konfiguracja oparta na ts-node działa dalej, jeśli projekt zostaje przy TypeScript 6 (npm install --save-dev typescript@6) i ma tsconfig.json, nawet pusty {}. Bez niego ts-node wraca do wbudowanych ustawień domyślnych, które zawierają rozwiązywanie modułów node10 oznaczone przez TypeScript 6 jako przestarzałe, i npx ts-node index.ts kończy działanie bez uruchomienia pliku i bez wypisania błędu.
Deno i Bun
Oba środowiska traktują TypeScript jako pełnoprawny typ pliku:
deno run index.ts # runs without checking
deno check index.ts # type-checks, reports errors, runs nothing
bun index.ts # runs without checking
Żadne nie wymaga zainstalowanego typescript ani tsconfig.json i oba obsługują enum oraz inne funkcje, których nie da się po prostu usunąć. Deno dostarcza własną kopię kompilatora TypeScript dla deno check. Bun tylko wycina typy, więc w projekcie Bun nadal instalujesz typescript i uruchamiasz tsc --noEmit, żeby znaleźć błędy typów.
Błędy typów zatrzymują program tylko z tsc
Tylko ścieżki, które najpierw uruchamiają tsc, odmawiają uruchomienia programu z błędami typów. Edytor na tej stronie jest jedną z nich, więc ten blok zatrzymuje się na kompilatorze:
index.ts(6,21): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
Zapisany jako plik i uruchomiony przez node index.ts, npx tsx index.ts lub bun index.ts, ten sam kod działa i wypisuje 12, bo 3 * "4" konwertuje string. Dlatego warto trzymać tsc --noEmit w obiegu, nawet gdy kod uruchamia szybsze narzędzie:
{
"scripts": {
"dev": "tsx watch src/index.ts",
"typecheck": "tsc --noEmit"
}
}
Którego użyć?
- Nauka albo szybki test: przycisk Run na tych stronach albo edytor online.
- Skrypt lub małe narzędzie na aktualnym Node.js:
node index.ts, zerasableSyntaxOnlyw konfiguracji, żeby edytor oznaczał wszystko, co Node by odrzucił. - Dowolny projekt Node.js, dowolna składnia:
tsxdo uruchamiania,tsc --noEmitdo sprawdzania. - Biblioteka lub cokolwiek, co publikujesz:
tsc, bo generuje też pliki.d.tspotrzebne twoim użytkownikom. - Kod front-endowy: twój bundler lub framework (Vite, Next.js, Angular CLI) uruchamia TypeScript za ciebie; dodaj
tsc --noEmitdo sprawdzania.
Najczęściej zadawane pytania
Jak uruchomić plik TypeScript?
Klasyczny sposób ma dwa kroki: npx tsc kompiluje .ts do .js, a potem node dist/index.js uruchamia wynik. W Node.js 22.18 lub 23.6 i nowszych możesz też uruchomić node index.ts bezpośrednio, o ile plik używa tylko składni typów, którą da się usunąć. npx tsx index.ts uruchamia dowolny plik TypeScript w jednym kroku.
Czy Node.js potrafi uruchomić TypeScript bezpośrednio?
Tak. Od Node.js 23.6 i 22.18 node file.ts działa bez flag: Node usuwa adnotacje typów i uruchamia resztę. Nie sprawdza typów, ignoruje tsconfig.json i odrzuca składnię wymagającą generowania kodu, taką jak enum, namespace z kodem wykonywalnym i parameter properties w konstruktorze.
Czy ts-node działa z TypeScript 7?
Nie. ts-node wywołuje JavaScriptowe API kompilatora, którego pakiet typescript 7 nie udostępnia, więc wywala się przy starcie (Cannot read properties of undefined (reading 'fileExists')). Jego ostatnie wydanie to 10.9.2 z grudnia 2023. Użyj tsx, type strippingu wbudowanego w Node albo zostań przy ts-node z TypeScript 6.
Czym różni się tsx od ts-node?
tsx tylko usuwa typy (przez esbuild) i uruchamia wynik, więc startuje szybko i nigdy nie zgłasza błędów typów. ts-node domyślnie sprawdza typy kompilatorem TypeScript, przez co jest wolniejszy i zależy od JavaScriptowego API kompilatora. Większość projektów łączy dziś tsx lub node file.ts do uruchamiania z tsc --noEmit do sprawdzania.
Czy jest TypeScript online do testowania kodu?
Tak. Bloki kodu na tych stronach dokumentacji i edytor online TypeScript w Coddy kompilują twój kod przez TypeScript 7 i go uruchamiają, pokazując błędy kompilatora albo wynik programu. Oficjalny TypeScript Playground na typescriptlang.org pokazuje wygenerowany JavaScript i błędy.