Node.jsでTypeScriptをネイティブ実行する方法

Node.js 23.6.0は、TypeScript開発者にとって転換点となります。ts-nodeやtscなどのトランスパイルツールを使わずに、.ts
ファイルを直接実行できるようになりました。このネイティブTypeScriptサポートにより、ビルドステップを排除しながら、IDE経由でタイプセーフティを維持することで、開発ワークフローが合理化されます。
このガイドでは、基本的なセットアップから本番環境での考慮事項まで、Node.jsでTypeScriptをネイティブ実行するために必要なすべてを網羅します。型除去(type stripping)の仕組み、サポートされるTypeScript機能、プロジェクトを最適な互換性で設定する方法を学習できます。
重要なポイント
- Node.js 23.6.0はトランスパイレーションなしでTypeScriptファイルを直接実行
- 型除去により、コード構造を保持しながら型注釈を削除
- 一般的なTypeScript機能の大部分が動作するが、enumsとnamespaceには回避策が必要
- import文には
.ts
拡張子を含める必要がある - ネイティブ実行により、従来ツールと比較して2〜3倍高速な起動時間を実現
クイックスタート: Node.js 23.6.0でTypeScriptを実行
ネイティブ実行を実証するために、シンプルなTypeScriptファイルから始めましょう:
// greeting.ts
function greet(name: string): string {
return `Hello, ${name}!`
}
console.log(greet("TypeScript"))
Node.js 23.6.0以降では、これを直接実行できます:
node greeting.ts
以上です—コンパイルステップは不要です。Node.jsが型注釈を除去して、残りのJavaScriptを実行します。
Node.jsのバージョンを確認するには:
node --version # v23.6.0以上である必要があります
初回実行時に実験的機能の警告が表示されます:
ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
開発時にこの警告を抑制するには:
node --disable-warning=ExperimentalWarning greeting.ts
または永続的に設定:
export NODE_OPTIONS="--disable-warning=ExperimentalWarning"
Node.jsにおける型除去の理解
型除去は、従来のTypeScriptトランスパイレーションとは根本的に異なります。TypeScriptをJavaScriptに変換するのではなく、Node.jsは元のコード構造を保持しながら型注釈を単純に削除します。
型除去中に発生する処理は以下の通りです:
// 元のTypeScript
function calculate(a: number, b: number): number {
return a + b
}
// 型除去後(Node.jsが実行するもの)
function calculate(a , b ) {
return a + b
}
空白の保持に注目してください—これにより、ソースマップを必要とせずに、デバッグ用の正確な行番号が維持されます。
パフォーマンス上の利点
ネイティブTypeScript実行は、大幅なパフォーマンス向上を提供します:
- トランスパイレーションオーバーヘッドなし: 中間ステップなしの直接実行
- 高速起動時間: ts-nodeの120msに対して約45ms
- メモリ使用量削減: メモリにトランスパイラーが読み込まれない
- 簡素化されたデバッグ: 元の行番号が保持される
Node.jsにおけるTypeScriptサポートの進化
進化を理解することで、適切なアプローチを選択できます:
v22.6.0: 初期型除去
node --experimental-strip-types app.ts
基本的な型削除のみ—TypeScript固有の構文サポートなし。
v22.7.0: 型変換
node --experimental-transform-types app.ts
変換によるenumsとnamespaceのサポートを追加。
v23.6.0: デフォルト型除去
node app.ts # 型除去がデフォルトで有効
基本的なTypeScript実行にフラグは不要。
サポートされるTypeScript機能と制限事項
動作するもの
Node.jsのネイティブTypeScriptは、日常的なTypeScript機能の大部分をサポートします:
// ✅ 型注釈
let count: number = 0
// ✅ インターフェース
interface User {
id: number
name: string
}
// ✅ 型エイリアス
type Status = 'active' | 'inactive'
// ✅ ジェネリクス
function identity<T>(value: T): T {
return value
}
// ✅ 型インポート
import type { Config } from './types.ts'
動作しないもの
一部のTypeScript固有機能には回避策が必要です:
機能 | サポート | 回避策 |
---|---|---|
Enums | ❌ | ユニオン型またはconstオブジェクトを使用 |
Namespaces | ❌ | ESモジュールを使用 |
パラメータープロパティ | ❌ | 明示的なプロパティ宣言 |
JSX/TSX | ❌ | 従来のトランスパイレーションを使用 |
デコレーター | ❌ | V8サポートを待つ |
回避策の例:
// ❌ Enum(サポートされていない)
enum Status {
Active,
Inactive
}
// ✅ ユニオン型の代替
type Status = 'active' | 'inactive'
// ✅ constオブジェクトの代替
const Status = {
Active: 'active',
Inactive: 'inactive'
} as const
Discover how at OpenReplay.com.
ファイル拡張子とモジュールシステム
Node.jsはファイル拡張子を使用してモジュール処理を決定します:
.ts
- package.jsonの"type"
フィールドに従う(ESMまたはCommonJS).mts
- 常にESMとして扱われる.cts
- 常にCommonJSとして扱われる
重要:ローカルインポートには.ts
拡張子を含める必要があります:
// ❌ 従来のTypeScript
import { utils } from './utils'
// ✅ Node.jsネイティブTypeScript
import { utils } from './utils.ts'
ネイティブTypeScript用のtsconfig.json設定
Node.jsは実行時にtsconfig.jsonを読み取りませんが、適切な設定によりIDEサポートと型チェックが確保されます:
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"moduleResolution": "nodenext",
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": false,
"verbatimModuleSyntax": true,
"strict": true,
"noEmit": true
}
}
主要設定の説明:
allowImportingTsExtensions
: インポートパスでの.ts
を許可rewriteRelativeImportExtensions
:.ts
拡張子を保持するためfalseに設定verbatimModuleSyntax
: 明示的な型インポートを強制noEmit
: 意図しないJavaScript生成を防止
型チェックを別途実行:
tsc --noEmit
従来のTypeScriptツールからの移行ガイド
ts-nodeからの移行
- ts-node依存関係を削除:
npm uninstall ts-node
- package.jsonスクリプトを更新:
// 変更前
"scripts": {
"dev": "ts-node src/index.ts"
}
// 変更後
"scripts": {
"dev": "node src/index.ts"
}
- サポートされていない機能を処理(enumsをunionsに変換)
tscコンパイルからの移行
- ビルドステップを削除:
// これらのスクリプトを削除
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
// 代わりにこれを使用
"scripts": {
"start": "node src/index.ts"
}
- CI/CDパイプラインを更新してコンパイルをスキップ
パフォーマンス比較
ネイティブTypeScript実行は大幅な改善を示します:
指標 | ネイティブTypeScript | ts-node | tsc + node |
---|---|---|---|
起動時間 | 約45ms | 約120ms | 約200ms |
メモリ使用量 | ベースライン | +30MB | +10MB |
ビルドステップ | なし | なし | 必要 |
よくある落とし穴と解決策
インポートパスエラー
// エラー: Cannot find module './utils'
import { helper } from './utils'
// 解決策: .ts拡張子を含める
import { helper } from './utils.ts'
サポートされていない構文
// エラー: Enums are not supported
enum Color { Red, Blue }
// 解決策: constオブジェクトを使用
const Color = { Red: 0, Blue: 1 } as const
型チェックの混同
覚えておいてください:Node.jsは型チェックを実行しません。型検証には常にtsc --noEmit
を実行してください。
本番環境での考慮事項
ネイティブTypeScriptを使用すべき場合
- 開発環境
- プロトタイプと実験
- 小規模スクリプトとユーティリティ
- 実験的機能に対応できるチーム
避けるべき場合
- 本番アプリケーション(安定版まで)
- 完全なTypeScript機能が必要なプロジェクト
- 安定したツールが必要なチーム
- 複雑なビルドパイプライン
Docker調整
# 変更前
FROM node:23-alpine
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]
# 変更後
FROM node:23-alpine
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["node", "src/index.ts"]
結論
Node.js 23.6.0のネイティブTypeScriptサポートは、開発ワークフローの大幅な簡素化を表しています。トランスパイレーションステップを排除することで、ビルドツールの設定よりもコード記述に集中できます。TypeScript固有の構文に関する制限は存在しますが、ほとんどの開発シナリオにおける利点は魅力的です。
まず開発環境でネイティブTypeScriptを試し、既存プロジェクトを段階的に移行し、TypeScriptがJavaScriptが動作するあらゆる場所で実行される未来に備えましょう。この機能が安定化するにつれて、より広範な採用と今後のNode.jsリリースでの機能拡張が期待されます。
よくある質問
技術的には可能ですが、本番使用はまだ推奨されません。この機能はまだ実験的であり、変更される可能性があります。開発環境、プロトタイプ、重要でないアプリケーションで使用してください。本番環境では、機能が安定するまで従来のトランスパイレーションを継続使用してください。
はい、型チェックのためにTypeScriptを開発依存関係として保持すべきです。Node.jsは型を検証せずに除去するだけです。開発中またはCIパイプラインで型エラーを捕捉するために、tsc --noEmitを別途実行してください。
ネイティブTypeScriptでは、従来のTypeScriptツールとは異なり、インポートパスに明示的な.ts拡張子が必要です。すべてのローカルインポートを'./module'から'./module.ts'に更新してください。外部パッケージのインポートには拡張子は不要です。
シンプルなケースではenumsをユニオン型に、数値enumsではas constアサーション付きのconstオブジェクトに置き換えてください。文字列enumsの場合、ユニオン型が完璧に動作します。このアプローチは実際により木揺らし(tree-shakeable)に優しく、現代のTypeScriptプラクティスとよく合致します。
Node.jsチームは、パフォーマンス上の理由から完全なトランスパイレーションではなく型除去に焦点を当てています。enumsやデコレーターなどのランタイム変換が必要な機能は、V8がネイティブに実装する際にサポートを得る可能性がありますが、目標は完全なTypeScript互換性ではなく、高速で最小限の処理です。
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.