結論:enumは既定の型除去だけでは実行できない
Node.js v24.19.0の組み込みTypeScript対応は、消してもJavaScriptとして成立する型構文を取り除く軽量機能です。enumは実行時の値を作るJavaScript生成が必要なため、既定のstrip-onlyではERR_UNSUPPORTED_TYPESCRIPT_SYNTAXになります。
小さい文字列enumならconstオブジェクトとas constへ書き換えます。既存enumの動作を保つなら通常コンパイルか対応ランナーを使います。tsconfig.jsonの変更だけでNode.jsがenumを変換することはありません。
1. Node.jsの版と最小例を確認する
node --versionこの記事はv24.19.0の既定動作を基準にします。例は常にESモジュールになる.mtsを使います。.ctsはCommonJS、.tsは通常のパッケージ判定です。
state-enum.mtsを作ります。
enum TaskState {
Waiting = "waiting",
Done = "done",
}
function printState(state: TaskState): void {
console.log(state);
}
printState(TaskState.Waiting);既定の型除去で直接実行します。
node state-enum.mts行番号などは環境で異なりますが、エラーの要点は次の形です。実測ログではなく、公式仕様に基づく説明用の想定例です。
ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX
TypeScript enum is not supported in strip-only mode
2. なぜ型注釈は消せてもenumは消せないのか
型エイリアスや型注釈は、削除してもJavaScriptとして成立します。
type UserId = string;
const id: UserId = "u-1";
console.log(id);型部分を除けば次のJavaScriptが残ります。
const id = "u-1";
console.log(id);一方、enumは実行時に参照するオブジェクトが必要です。概念的には次のようなコードを新たに生成しなければなりません。
var TaskState;
(function (TaskState) {
TaskState["Waiting"] = "waiting";
TaskState["Done"] = "done";
})(TaskState || (TaskState = {}));既定の型除去は、このJavaScript生成を担当しません。
| 構文 | 既定の型除去 | 理由 |
|---|---|---|
| 型注釈、type、interface | 可能 | 消してもJSが成立 |
| enum | 不可 | 実行時の値が必要 |
| 実行時コードを含むnamespace | 不可 | 値や処理の生成が必要 |
| 型だけのnamespace | 可能 | 実行時コードが残らない |
| parameter properties | 不可 | 代入処理の生成が必要 |
3. 小さい文字列enumはconstオブジェクトへ書き換える
const TaskState = {
Waiting: "waiting",
Done: "done",
} as const;
type TaskState = (typeof TaskState)[keyof typeof TaskState];
function printState(state: TaskState): void {
console.log(state);
}
printState(TaskState.Waiting);node state-const.mts想定される出力です。
waitingas constや型定義は削除できるため、残りは有効なJavaScriptになります。ただし、数値enumの逆引きなど、enumの全動作を再現する一括置換ではありません。単純な文字列値の一覧に限って検討します。
4. 既存enumを維持するなら通常コンパイルか対応ランナーを使う
enumの意味を保つ場合は、TypeScriptコンパイラでJavaScriptを生成する方法が基本です。
npm install --save-dev typescriptsrc/state.mtsを対象にした構成例です。
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"outDir": "dist",
"rootDir": "src",
"strict": true,
"noEmitOnError": true
},
"include": ["src/**/*.mts"]
}npx tsc.mtsから出力された.mjsを実行します。
node dist/state.mjs開発中の直接実行には、Node.js公式資料が例示するtsxのような対応ランナーも使えます。
npm install --save-dev tsxnpx tsx src/state.mts5. erasableSyntaxOnlyで実行前に見つける
TypeScript 5.8以降のerasableSyntaxOnlyは、enumなど実行時の意味を持つ構文をコンパイル時に検出します。Node.jsへ変換機能を追加する設定ではありません。
{
"compilerOptions": {
"noEmit": true,
"target": "ESNext",
"module": "NodeNext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}npx tsc --noEmitverbatimModuleSyntaxは、型だけのimportをimport typeで明示し、importの自動除去に頼らないための設定です。enumを変換する機能ではありません。
よくある質問
tsconfig.jsonだけ直せばenumを実行できますか
できません。組み込み型除去はtsconfig.jsonを読みません。erasableSyntaxOnlyは問題を事前検出する設定です。
nodeで.tsや.mtsを直接実行すると型チェックもされますか
されません。型チェックが必要なら、別に次のコマンドなどを実行します。
npx tsc --noEmitNode.js 24の--experimental-transform-typesは使えますか
v24.19.0の公式資料には、変換が必要な構文を扱う版依存の実験的選択肢として記載されています。
node --experimental-transform-types state-enum.mtsただし、現行のNode.js 26系資料ではv26.0.0で削除されています。全版共通の解決策にはせず、使用中の版を確認してください。主な選択肢は書き換え、通常コンパイル、対応ランナーです。


コメント