Node 現在跑得動你的 TypeScript——除了五件事
Type stripping 預設就開著,而它不是編譯,是刪除。有五個構造沒有「不需要執行期程式碼」的等價寫法可刪,每一個都會讓你的行程在啟動時就停下來。

你把建置步驟刪掉、跑 node server.ts,它動了。然後你部署上去,行程在印出任何東西
之前就結束了。
抹除不是編譯
這就是整個模型,而它解釋了全部五個失敗。Node 不編譯你的 TypeScript——它把標註
刪掉然後執行剩下的東西。型別、interface、satisfies、as:全部消失,
底下的 JavaScript 一個 byte 都沒變。這正是它不需要 source map、也不可能改變你的
程式行為的原因。
所以規則不是「哪些功能有支援」,而是:這個構造需不需要 Node 產生執行期程式碼? 需要的話就沒有東西可以刪,於是失敗。
檢查一個檔案
有 4 個 Node 抹不掉的構造
Node 實際會說什麼
SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode
可抹除的改寫
抹不掉
enum Colour {
Red,
Green,
}抹得掉
const Colour = {
Red: 0,
Green: 1,
} as const;
type Colour = (typeof Colour)[keyof typeof Colour];這是正規表示式檢查,不是 TypeScript 剖析器——真正的剖析器要好幾百 KB,而這一頁的預算是 220KB。它可能會誤報。 錯誤訊息錄自 Node v25.9.0,2026-08-06。
那是正規表示式檢查,不是 TypeScript 剖析器——真的剖析器要好幾百 KB,而這一頁的 JavaScript 預算是 220KB。它會誤報,而這是誠實的取捨:一個承認自己是檢查清單的 清單,比一個假裝自己是編譯器的工具安全。
裡面每一則錯誤訊息都是真的在 Node v25.9.0 上執行後錄下來的,不是從文件抄的。 你會把那些字串貼進搜尋框,所以它們必須逐字正確。
五個,以及它們各自為什麼需要產生程式碼
enum 在執行期會產生一個物件——你可以雙向索引它。把宣告刪掉,
呼叫端就會指向不存在的東西。
SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]:
TypeScript enum is not supported in strip-only mode
const enum 的失敗完全一樣,這會讓以為它會被內聯掉的人意外。
含有執行期值的 namespace 是同一個故事——namespace Config { export let retries = 3 }
必須變成一個物件。只含型別的 namespace 沒問題,Node 接受;那是唯一的例外,
而且很容易漏掉,因為錯誤訊息只說「namespace declaration」。
建構子參數屬性純粹是一次賦值的語法糖,而那次賦值得由 Node 幫你寫出來:
constructor(private readonly name: string) {}
// 必須產生:this.name = name
import fs = require('node:fs') 需要被改寫成真正的 import。
裝飾器是五個裡的異類。它不是「不支援的 TypeScript」——它還不是 JavaScript,
是一個 TC39 Stage 3 提案。Node 沒有東西可以抹,所以它更早、以不同的方式失敗:
一個普通的 SyntaxError: Invalid or unexpected token,沒有
ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX 這個代碼可以拿去搜。
該做的三件事
- 在 tsconfig 打開
erasableSyntaxOnly。 它會讓編譯器在型別檢查階段就擋下這 五個——那才是你想發現它們的地方,而不是在生產環境的行程啟動時。 - 把前四個改寫掉。 它們都有可抹除的等價寫法(上面的元件裡都有), 而且每一個都比它取代的東西更接近普通的 JavaScript。
- 裝飾器才是真正的分岔。 它是唯一沒有可抹除改寫的。如果你的專案依賴它, 你就是要保留建置步驟——那是完全合理的答案,只是要讓它是一個決定, 而不是一個發現。
常見追問
為什麼 Node 不乾脆編譯它們?
因為抹除跟編譯是兩件事。抹除只是拿掉標註,底下的 JavaScript 一個 byte 都沒變, 所以不需要 source map,也不可能改變行為。一旦它開始產生程式碼——一個 enum 物件、 一次欄位賦值——它就是編譯器了,連同版本相容與正確性的整片表面積。
型別專用的 namespace 也會壞嗎?
不會。只含型別的 namespace 是可抹除的,Node 接受。只有宣告了執行期值的 namespace 才失敗。已在 Node v25.9.0 上實測確認。
enum 要用什麼取代?
一個凍結的物件加上一個推導出來的型別。`const Colour = { Red: 0, Green: 1 } as const` 配上 `type Colour = (typeof Colour)[keyof typeof Colour]`,呼叫端寫法一樣, 而且它是任何工具都看得懂的普通 JavaScript。
裝飾器呢?
沒有可抹除的改寫。裝飾器是 TC39 Stage 3 提案,不是 JavaScript,Node 沒有東西 可以抹。需要它的話你就還是需要建置步驟——tsc、SWC 或 esbuild。