Menu

TypeScriptの実行方法: tsc、Node.js、tsx、ts-node

.tsファイルを実行する5つの方法を解説します。tscでコンパイルしてJavaScriptを実行する、node file.ts で直接実行する(型ストリッピング)、tsxやts-nodeを使う、DenoやBunを使う。それぞれ型チェックをするか、どの構文に対応するか、どれを選ぶべきかをまとめます。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

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とエラーを確認できます。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める