TypeScriptのファイルはそのままでは実行できません。ブラウザーやJavaScriptエンジンは型注釈を理解しないからです。まず何かが型を取り除く必要があります。それは型のチェックも行うTypeScriptコンパイラー(tsc)か、型を取り除くだけの高速なツールのどちらかです。このページのコードを一番手軽に実行するには、Runボタンを使います。
出力:
[x] Install TypeScript
[ ] Run a .ts file
このドキュメントの実行可能なブロックはすべて同じ仕組みです。コードは strict を有効にしたTypeScript 7で型チェックされ、型エラーがないときだけ実行されます。もっと長いコードを試すなら、TypeScriptプレイグラウンド が同じエディターを1ページで使えます。このページの残りでは、自分のマシンで .ts ファイルを実行する方法を扱います。
選択肢の一覧
| コマンド | 型チェック | ビルドが必要 | enum、namespace、パラメータープロパティに対応 |
|---|---|---|---|
npx tsc のあと node dist/index.js | する | 必要 | する |
node index.ts(Node.js 22.18+、23.6+) | しない | 不要 | しない |
npx tsx index.ts | しない | 不要 | する |
npx ts-node index.ts | する | 不要 | する(TypeScript 7では動かない) |
deno run index.ts | しない(deno check はする) | 不要 | する |
bun index.ts | しない | 不要 | する |
意外に思われるのは最初の列です。高速な選択肢のほとんどは、型エラーのあるコードでもそのまま実行します。一般的なプロジェクトでは、そのどれかでコードを実行し、エラーを見つけるために tsc --noEmit を別に(エディターとCIで)実行します。
tscでコンパイルしてからNodeで実行する
どこでも動き、すべてをチェックする方法です。プロジェクトにTypeScriptがインストールされていて、tsconfig.json で "rootDir": "./src" と "outDir": "./dist" を設定している場合は次のとおりです。
npx tsc
node dist/index.js
tsc はすべてのファイルを型チェックしてから、.js ファイルを dist に書き出します。プロジェクトなしで1ファイルだけ扱うなら、ファイル名を渡します。この場合はデフォルトのオプションが使われ、index.ts の隣に index.js が書き出されます。
npx tsc index.ts
node index.js
(フォルダーに tsconfig.json があると、tsc はファイル名の指定を error TS5112 で拒否します。単に npx tsc を実行するか、--ignoreConfig を付けてください。)
デフォルトでは、tsc は型エラーがあってもJavaScriptを書き出すので、チェックに失敗したプログラムを node が実行できてしまいます。これを防ぐには設定に "noEmitOnError": true を加えるか、スクリプトでコマンドをつなげて、最初のステップが成功したときだけ2番目が実行されるようにします。
{
"scripts": {
"build": "tsc",
"start": "tsc && node dist/index.js"
}
}
開発中は、npx tsc --watch で保存のたびに再コンパイルできます。
Node.jsでTypeScriptを直接実行する
最近のNode.jsは .ts ファイルを自分で実行します。
node index.ts
Nodeは型注釈を空白に置き換えて取り除き(スタックトレースの行番号がずれないようにするため)、残りを実行します。この機能はNode.js 23.6.0と22.18.0からデフォルトで有効で、24.3.0と22.18.0からは警告も出なくなり、Node.js 24.12.0と25.2.0で安定版になりました。この機能を持つそれ以前のリリース(22.6から22.17、23.0から23.5)では、node --experimental-strip-types index.ts のようにフラグが必要です。
これには4つのルールがあります。
- 型チェックはしない。
const age: number = "forty"を含むファイルもそのまま実行され、fortyと表示されます。 - 消去できる構文だけ。 消えるのではなくJavaScriptのコードにならなければいけない構文は拒否されます。
enum、実行時コードを含むnamespaceブロック、constructor(private name: string)のようなコンストラクターのパラメータープロパティ、import x = require()のエイリアスです。NodeはSyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only modeで停止します。 tsconfig.jsonは無視される。pathsやtargetなどのオプションは効きません。- importには実際のファイル名が必要。
import { add } from "./math.ts"のように拡張子を付けて書き、型だけのimportにはtypeを付けます(import { add, type Pair } from "./math.ts")。typeがないと、NodeはPairという実行時のexportを探し、SyntaxError: The requested module './math.ts' does not provide an export named 'Pair'で失敗します。
2つのコンパイラーオプションを使うと tsc にも同じルールを守らせることができ、Nodeより先にエディターが警告してくれます。"erasableSyntaxOnly": true は enum に対して error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. を報告し、"verbatimModuleSyntax": true は型だけのimportに type キーワードを要求します。importに .ts の拡張子を書いたまま tsc でもコンパイルしたい場合は、"rewriteRelativeImportExtensions": true を加えます。出力では ./math.ts が ./math.js に変わります。
Node.js 24には --experimental-transform-types もあり、enumやパラメータープロパティを拒否せずにコードを生成します。ただし ExperimentalWarning が表示され、Node.js 26でこのフラグは削除されたので、これに頼るのはやめましょう。
次のブロックは、node index.ts が拒否する機能を2つ使っています。ここで実行できるのは、エディターがTypeScriptコンパイラーでコンパイルし、どちらについてもJavaScriptを生成するからです。
同じコードの消去可能な版では、const オブジェクトと普通のフィールドを使います。これならNodeでそのまま実行できます。
tsx
tsx は、設定なしで、構文の制限もなく、TypeScriptファイルを1ステップで実行します。
npm install --save-dev tsx
npx tsx index.ts
npx tsx watch index.ts # rerun on every change
esbuildでコードを変換するので、enum、namespace、パラメータープロパティが動き、拡張子のないimportもバンドラーと同じように解決されます。Nodeの型ストリッピングと同じく、型チェックはしません。型ストリッピングより前のNode.jsでスクリプト、開発サーバー、テストを動かすときや、Nodeが拒否する構文をコードが使っているときによく選ばれます。
ts-node
ts-nodeは長年、Node.jsでTypeScriptを実行する標準的な方法でした。今も多くのチュートリアルや古いプロジェクトで使われています(npx ts-node index.ts、node -r ts-node/register)。デフォルトでは、TypeScriptコンパイラーのJavaScript APIを使って型チェックします。
そのAPIこそ、TypeScript 7が提供しないものです。TypeScript 7のコンパイラーはネイティブのプログラムで、typescript 7 パッケージはJavaScript向けのコンパイラーAPIを公開していません。TypeScript 7がインストールされていると、ts-nodeは何も実行しないうちにクラッシュします。
TypeError: Cannot read properties of undefined (reading 'fileExists')
at readConfig (/project/node_modules/ts-node/dist/configuration.js:91:33)
ts-nodeの最新リリース10.9.2は2023年12月のものです。新しいコードには tsx か node index.ts を使いましょう。ts-nodeに依存する既存の環境は、プロジェクトがTypeScript 6のまま(npm install --save-dev typescript@6)で、tsconfig.json(空の {} でもよい)があれば動き続けます。これがないとts-nodeは組み込みのデフォルトに戻り、その中にTypeScript 6で非推奨になった node10 モジュール解決が含まれるため、npx ts-node index.ts はファイルを実行せず、エラーも表示せずに終了します。
DenoとBun
どちらのランタイムもTypeScriptを正式なファイル形式として扱います。
deno run index.ts # runs without checking
deno check index.ts # type-checks, reports errors, runs nothing
bun index.ts # runs without checking
どちらも typescript のインストールや tsconfig.json は不要で、enum などの消去できない機能にも対応しています。Denoは deno check のために独自のTypeScriptコンパイラーを同梱しています。Bunは型を取り除くだけなので、Bunのプロジェクトでも型エラーを見つけるには typescript をインストールして tsc --noEmit を実行します。
型エラーでプログラムが止まるのはtscだけ
型エラーのあるプログラムの実行を拒否するのは、先に tsc を実行する方法だけです。このページのエディターもそのひとつなので、次のブロックはコンパイラーの段階で止まります。
index.ts(6,21): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
同じコードをファイルに保存して node index.ts、npx tsx index.ts、bun index.ts で実行すると、3 * "4" が文字列を変換するため、実行されて 12 と表示されます。高速なツールでコードを実行する場合でも tsc --noEmit を開発の流れに残しておくべき理由はここにあります。
{
"scripts": {
"dev": "tsx watch src/index.ts",
"typecheck": "tsc --noEmit"
}
}
どれを使えばよいか
- 学習中、またはちょっとした確認: このページのRunボタンか、プレイグラウンド。
- 最近のNode.jsで動くスクリプトや小さなツール:
node index.ts。設定にerasableSyntaxOnlyを入れておけば、Nodeが拒否するものをエディターが指摘してくれます。 - Node.jsのプロジェクト全般(構文を問わない): 実行に
tsx、チェックにtsc --noEmit。 - ライブラリや公開するもの:
tsc。利用者が必要とする.d.tsファイルも書き出すからです。 - フロントエンドのコード: バンドラーやフレームワーク(Vite、Next.js、Angular CLI)がTypeScriptを処理してくれます。チェックには
tsc --noEmitを加えます。
よくある質問
TypeScriptのファイルを実行するには?
昔からの方法は2段階です。npx tsc で .ts を .js にコンパイルし、node dist/index.js で出力を実行します。Node.js 22.18または23.6以降なら、ファイルが消去できる型構文だけを使っている限り node index.ts で直接実行することもできます。npx tsx index.ts はどんなTypeScriptファイルでも1ステップで実行します。
Node.jsはTypeScriptを直接実行できますか?
できます。Node.js 23.6と22.18以降では、フラグなしで node file.ts が動きます。Nodeは型注釈を取り除いて残りを実行します。型チェックはせず、tsconfig.json を無視し、enum、実行時コードを含む namespace、コンストラクターのパラメータープロパティのようにコード生成が必要な構文は拒否します。
ts-nodeはTypeScript 7で動きますか?
動きません。ts-nodeはコンパイラーのJavaScript APIを呼び出しますが、typescript 7 パッケージはそれを提供しないため、起動時にクラッシュします(Cannot read properties of undefined (reading 'fileExists'))。最新リリースは2023年12月の10.9.2です。tsx かNode自身の型ストリッピングを使うか、ts-nodeを使い続けるならTypeScript 6のままにしてください。
tsxとts-nodeの違いは何ですか?
tsxは(esbuildで)型を取り除いて結果を実行するだけなので、起動が速く、型エラーは一切報告しません。ts-nodeはデフォルトでTypeScriptコンパイラーを使って型チェックするため遅く、コンパイラーのJavaScript APIに依存します。今ではほとんどのプロジェクトが、実行にはtsxか node file.ts、チェックには tsc --noEmit という組み合わせを使っています。
オンラインでTypeScriptを試せるサンドボックスはありますか?
あります。このドキュメントのコードブロックとCoddyのTypeScriptプレイグラウンドは、コードをTypeScript 7でコンパイルして実行し、コンパイルエラーかプログラムの出力を表示します。typescriptlang.orgの公式TypeScript Playgroundでは、出力されるJavaScriptとエラーを確認できます。