Whitespace substitution only works when deleting the types leaves valid JavaScript behind. A few TypeScript constructs emit runtime code, so there is nothing to blank out, and Node refuses them by name with ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX.
$ node enum.ts SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript enum is not supported in strip-only mode code: 'ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX' $ node param.ts SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript parameter property is not supported in strip-only mode
The message names the construct every time — "namespace declaration" and "import equals declaration" for the other two. Each has a plain replacement, usually the better code anyway.
| Not erasable | Write instead |
|---|---|
| enum Level { ... } | as const object plus a type alias |
| namespace X { ... } | A module with named exports |
| constructor(private db: string) | A field assigned in the body |
| import fs = require('fs') | import fs from 'node:fs' |
| <string>value | value as string |
const Level = { Debug: 0, Info: 1, Warn: 2 } as const;
type Level = (typeof Level)[keyof typeof Level];
class Logger {
#level: Level;
constructor(level: Level) { this.#level = level; }
}
new Logger(Level.Info); // runs under plain nodeDeclaring the value and the type under one name gives you Level.Info in expressions and Level in annotations, exactly like an enum, but at runtime it is a plain object.
TypeScript 5.8 added erasableSyntaxOnly for this problem: the compiler rejects anything the runtime cannot strip, so the failure lands in your editor instead of on the first request that reaches the module. Pair it with verbatimModuleSyntax, which forces the type keyword on type-only imports; without it, stripping leaves a real import of a binding that does not exist at runtime.
$ npx tsc --noEmit enum.ts(1,6): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled. enum.ts(4,15): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.
Those two errors come from one file: an enum on line 1, a parameter property on line 4. Decorators are a separate case — a TC39 stage 3 proposal rather than TypeScript syntax, which Node does not transform and its parser rejects with SyntaxError: Invalid or unexpected token. Frameworks built on decorators for dependency injection still need a compile step; Express.js and MongoDB use none.