Skip to main content

Please Engage

Node.js Now Has TypeScript Type Stripping On By Default

Despite keeping up better with my RSS feed reader lately, I still missed that Node.js v22.18.0 enables TypeScript type stripping by default! Apparently it has also been enabled in v24 since its initial release.

This is great news, because it means that with some important caveats, it is now possible to run TypeScript natively in Node without needing to specify the --experimental-strip-types flag. The caveats boil down to the fact that not every TypeScript language feature can be cleanly stripped to create valid JavaScript — a small handful of features require the TypeScript compiler to generate JavaScript code in order to fully function.

Luckily, in TypeScript v5.8 they introduced the --erasableSyntaxOnly option. This raises errors when you use one of these features that would cause Node.js to throw a JS parse error even after type stripping.

The full list of these non-erasable language features is thankfully small, and, in my usage of TypeScript, quite manageable:

I don’t think I’ve ever used executable code in a namespace or a module — the only time I use those is if I need to extend global or package types. I don’t think I’ve ever used import = aliases. And I can easily live without parameter properties.

Lack of enums is probably the toughest pill to swallow. But the TypeScript docs for enums have a good suggestion — instead of creating an enum create an object with as const:

export const Direction = {
  Up: 1,
  Right: 2,
  Down: 3,
  Left: 4,
} as const

export type DirectionEnum = (typeof Direction)[keyof typeof Direction]

Hopefully this proposal for an as enum assertion gets some traction, since it would be nice to not need an extra [Name]Enum type.

There are two other TS options that are helpful for running type-stripped TS in Node: rewriteRelativeImportExtensions and verbatimModuleSyntax. The former helps ensure you can use .ts extensions in your import statements, and the latter avoids surprises from top-level side-effects when importing a TS module.