世界を動かす技術を、日本語で。

Node.jsがTypeScriptファイルを実行できるようになりました

概要

Node.js 22.18.0(LTS 'Jod')がリリース。 TypeScriptファイルの型情報除去(type stripping)がデフォルト有効化。 多数の依存ライブラリの更新やバグ修正を実施。 新機能・改善点やドキュメントの調整が含まれる。 一部機能は実験的で今後変更の可能性あり。

Node.js 22.18.0 'Jod' (LTS) 主な変更点

  • TypeScript型情報除去(type stripping)デフォルト有効化

    • TypeScriptファイル を追加設定なしで直接実行可能。
    • 例:node file.ts でTypeScriptファイルを実行、 型情報は自動的に除去
    • 一部サポートされない構文あり、詳細は公式ドキュメント参照。
    • 実験的機能 のため、将来的に仕様変更の可能性。
    • 無効化は--no-experimental-strip-typesフラグで対応。
  • 依存ライブラリのアップデート

    • amaro、sqlite、npm、googletest、minimatch、acorn、simdjson、zlibなどを最新バージョンへ更新。
    • セキュリティやパフォーマンス向上、バグ修正。
  • ESM/モジュールシステムの改善

    • import.meta.mainの実装。
    • TypeScriptサポート関連のエラーメッセージ改善。
    • Coreモジュールのスキーマ変換やCJS/ESMローダーの強化。
  • ファイルシステム(fs)・パーミッション・その他APIの改善

    • AsyncIteratorによるfs-eventsバースト処理の正確な対応。
    • パーミッションモデルのspawn時フラグ伝播強化。
    • readBigIntsオプションのsqlite接続レベル対応。
    • 新APIfileURLToPathBufferの追加。
  • Worker/REPL/テスト関連の拡張

    • Workerのasync disposableサポート。
    • REPLのevalエラー・タブ補完バグ修正。
    • テストの安定性向上や新たな既知の問題テスト追加。
  • ドキュメント・メタデータの更新

    • Watchモード関連フラグのドキュメント追加。
    • コラボレーター・連絡先情報の更新。
    • 各種APIドキュメントの修正・安定性マーカーの統一。
  • バグ修正・内部最適化

    • メモリリークや誤ったタイムアウト処理の修正。
    • 内部API・ビルド関連のクリーンアップ。
    • 既存コードのリファクタリングとコメントの整理。

TypeScript型情報除去の詳細

  • TypeScriptファイルをNode.jsで直接実行可能

    • 追加ツールや設定不要。
    • 型情報は実行時に自動除去され、 JavaScriptとして評価
  • 制限事項

    • 一部のTypeScript構文は未対応。
    • 詳細や既知の制限は公式ガイド参照。
  • 実験的機能

    • 仕様が今後変更される可能性。
    • 安定運用が必要な場合は--no-experimental-strip-typesで無効化を推奨。

その他の注目機能・改善点

  • import.meta.main の実装により、モジュールのエントリーポイント判定が容易化。
  • AsyncIterator によるfsイベントバーストの正確な処理。
  • Workerスレッド のasync disposable対応でリソース管理が容易に。
  • readBigInts オプションでsqliteの大きな整数値も正確に扱えるように。
  • fileURLToPathBuffer APIでファイルURL→Buffer変換が簡単に。

ドキュメント・開発フローの強化

  • watchモード 関連フラグの詳細ドキュメント化。
  • コラボレーターや連絡先、API安定性マーカーなどの情報整理。
  • テストの安定性向上と自動化強化。

このリリースは、 TypeScriptユーザーモダンなNode.js開発者 にとって大きな利便性向上をもたらす内容。 詳細はNode.js公式リリースノートや各種ドキュメント参照。

Hackerたちの意見

これって型情報を取り除くことで動いてるみたいだから、せいぜいトランスパイルの手間を省けるだけで、安全性は向上しないって感じだね。

その通り!型チェックって時間がかかるし、コストもかかるからね。

スクリプトを実行するのに別のコンパイルステップがいらないのはいいね。型チェックが必要ならtscを使うし。

そうだね、「NodeはTypeScriptファイルを実行できる」って言うのはちょっと誤解を招くかも。もっと正確に言うなら「Nodeは.tsファイルの型情報をスペースに置き換えて、普通のJavaScriptとして実行しようとする」って感じかな。これだと基本的なTypeScriptファイルしか扱えないと思う。型システムをもっと活用し始めると、痛い目に遭うんじゃないかな。ちゃんとやるチャンスを逃したのは残念だね(サードパーティのプラグインに頼るんじゃなくて)。編集:もしビルド時に型チェックのためだけにTypeScriptを使ってるなら(つまり、最も基本的なTypeScriptファイル)、これが役立つかもしれない。でもTypeScriptは、クラスのアクセス修飾子、ジェネリクス、インターフェース、型エイリアス、列挙型、デコレーターなどの不足している機能のためにJavaScriptコードを生成するから、Nodeが実行時にそれをスペースに置き換えたら、厄介なことになるよ。

プロジェクトで同じ効果を得るためにtsxを使ってるよ。君が言ったように、ビルドやトランスパイルのステップを設定しなくて済むから、開発にはすごく便利だね。tsxには--watch機能もあって、TypeScriptのソースファイルからサーバーを立ち上げて、変更があったら自動で再起動してくれるんだ。もしかしたら、nodemonとこの新しいNodeの改善で、tsxなしでもできるようになるかも。実行時に型をチェックするには(それが有用な方法でできるのかは分からないけど)、v8に組み込まれる必要があるだろうし、それは全体的な書き直しになると思う。

そう、例えばenumは解析できないんだよね。

TypeScriptは安全性を向上させるって約束してたわけじゃないから、勘違いかもしれないね。でも、TypeScriptにはランタイムモードや情報がないから、結局は実行時に型チェッカーを無視しない限り、いつもその影響を受けることになる。ひどい型エラーがあっても、ts-nodeやtsxを実行するのを止めるものは何もないし。そういう意味では、TypeScriptはリントツールに近いね。

TypeScriptのデザイン目標の一つは、ソースコードから型に関する部分を全部取り除いても、有効なJavaScriptファイルが得られることなんだ。TypeScriptコンパイラはコードを生成しない(PureScriptとは違ってね)。型情報に基づいて、コードのさまざまな特性を静的にチェックする型チェッカー(例えばtsc)を実行できるけど、その後は型情報は消されるんだ。同じことがPythonにも言えるね:型アノテーションはランタイムでは無視される。似たようなことがJavaにもあって、バイトコードでは型情報が一部消される。特に、パラメータ化された型に関する情報はね。(実際の機械コードについては何も言わないけど。)

せいぜいトランスパイルの手間を省くだけで、安全性は向上しない。これはちょっと誤解を招くね。NodeがTSコードを実行できるからといって「安全性が向上する」わけじゃない。型チェックはそこで行われるわけじゃないからね。エディタやツールチェーンの他のポイントで型チェックはできるし。NodeがTSコードを実行できることで、TSコードを書く際の摩擦が減って、間接的に型安全性が助けられるんだ。

TypeScriptの使命は型を取り除くことなんだから、何が言いたいの?TypeScriptは絶対にJavaにはならないし、ランタイムリフレクションもないよ。

最近のNodeの進化には感心してるよ。DenoやBunのおかげでNodeが集中して改善してる。しばらく停滞してたからね。

Node自体の最近の改善点って何かある?最後に聞いた注目すべき改善点は、import/exportをちゃんとサポートするようになったことだけど(.mjsのハックはまだ必要なのかな?)、しばらく情報から離れてたから、最近の追加点を知りたいな。

それ、実際にあるの?私が関わってるプロジェクトでは、NodeのLTSリリースだけが重要で、最近のプロジェクトはまだNode 20だよ。

俺はまだenumが欲しい。

これとnode:testがあれば、Node.jsは今やほとんどのことに対してかなり魅力的なデフォルトだと思う。tsxで実行するのは、実際に起こった時に生活の質がすごく向上したけど、すべての問題を解決したわけじゃない。エッジでのランタイム型アサーションは主にzodで解決されてるし、ts-resttrpcのようなツールがあれば、フルスタックのTypeScriptが今はずっとやりやすくなってるよ。

これだね。2025年になって、Nodeエコシステムがやっとデフォルトで使えるようになった!ESMモジュールはNodeとTypeScriptの両方でちゃんと動くし、Nodeは.tsファイルを実行できるし、十分なテストランナーも内蔵されてる。--watch。より良い内蔵パッケージ - node:fs/promises - は、トップレベルのawaitで簡単に非同期ループができるからいいよね。関わったみんなを実用的に納得させるのに時間がかかったけど、今はいい感じだね。

これ、tsxは動くの?型が削除されても、JSXをJavaScriptに変換する必要があるよね。

SvelteがコードベースをTypeScriptに戻すか、見てみよう。

TSサポートがノードに直接あった方がいいと思う。最近はvitestのおかげで楽になったけど、.tsファイルのテスト環境を設定するのに、バランスを取るのにかなりの時間を無駄にしてきた。trpcとts-restは、私の意見では全然違うものだね。どちらも使うのは構わないけど、プロダクションでは扱いたくない。trpcは主にAPIのURLを所有できないことと、古いURLを優雅に廃止する管理が難しいから。ts-restは、自分でその設定を持ちたいっていうのがあって、通常はzodとAPIのリクエスト/レスポンスペアの共有型を使ってる。あと、明らかに「-rest」って名前のRPCツールをインポートするたびにちょっとイラッとする。

でも、やっぱりbunが勝者だね。最近bunを使い始めたけど、もうNode.jsには戻れないよ。ほんとに動くから。

NodeはまだREPLが優れてるけど、確かに同意する。Bunは本当に良いよね。私もそれを使ってる。

ブラウザも直接TypeScriptファイルを実行できるようになればいいのに。

いつか実現するかな! https://github.com/tc39/proposal-type-annotations

もう提案はあるみたいだよ、最近のニュースだね。

これが進むべき道だとは思うけど、なんかモヤモヤするよね。ESMの騒動、覚えてる?また数年同じことが繰り返されるのかも、今度はTypeScriptのバージョンや設定、tsgoが違うけど。いいニュースだね!

ウォッチモードに対応してる?パスエイリアスもサポートしてるの?

最近のバックエンドフレームワークは何が主流なの?まだExpress?

Expressはまだ人気だけど、最近はNext.jsやSvelteKitみたいなフルスタックフレームワークを使うプロジェクトが多いね。Fastify、NestJS(うーん)、Koa、HonoがExpressの現代的な代替だけど、どれもスタンダードとしては広まってないかな。小さいプロジェクトではPolka(https://github.com/lukeed/polka)が好きで、Goを使わないときはこれを使ってる。

個人的には、バックエンドでJSを使う理由はメタフレームワークのせいだと思う。そうじゃなきゃ、あんまり価値がないよね。Nuxtの場合はnitroだけど、SvelteKitや他のReactのメタフレームワークについてはよくわからない。

やったー!ついに!<3