nyc (the Istanbul CLI, v18) cannot load a .ts file at all — it hijacks Node’s .ts extension handler and compiles TypeScript as raw JavaScript, throwing SyntaxError: Unexpected token ':'. Discovered during FKITDEV-8387; it means vuer_oss/supervisor_vuer_oss_e2e_test.conf has been broken since FKITDEV-8246 “TS Magic” landed in January 2026.

Gotcha

npx nyc node <anything-that-requires-a-.ts-module> crashes at the first .ts require. nyc’s coverage require-hook (append-transformdefault-require-extensions/js.js) replaces the .ts extension compiler with the JavaScript compiler, so type annotations reach V8 as JS syntax and blow up. Node’s own runtime type-stripping is bypassed because nyc’s hook wins.

Symptoms

SyntaxError: Unexpected token ':'
    at Module.replacementCompile (node_modules/append-transform/index.js:60:13)
    at module.exports (node_modules/default-require-extensions/js.js:7:9)

The Unexpected token ':' is a type annotation (foo: string) being parsed as JavaScript.

Root cause

nyc installs a require hook to instrument every loaded module for coverage. It does this by wrapping the extension handlers in require.extensions. For .ts it routes through default-require-extensions.js compiler (js.js) via append-transform — i.e. it treats .ts source as JavaScript before instrumenting. Node ≥ 22.18 would normally strip the types (see typescript-in-vuer-repos), but nyc’s hook replaces that handler, so the raw TS text is compiled as JS.

Neither --extension=.ts nor --include '**/*.ts' helps — those flags only widen which files nyc instruments, they do not teach nyc’s compiler about TypeScript syntax.

Consequence: the e2e supervisor conf is dead

vuer_oss/supervisor_vuer_oss_e2e_test.conf wraps every one of the 7 entrypoints as npx nyc node <file>.js. And server.js already requires six .ts services at boot:

  • server.js:48, 83, 99, 108, 109, 110

So the very first .ts require under nyc throws. The conf has been broken since TS Magic landed (Jan 2026). Nothing outside the git index references the file — no CI job invokes it, no Docker / deploy repo copies it — which is why the breakage went unnoticed.

Fix (own ticket)

Two options, both simple:

  1. Swap nyc for c8. c8 uses V8’s built-in coverage (NODE_V8_COVERAGE) and installs no require hook, so Node’s native type-stripping runs untouched and .ts loads normally. Drop-in for the npx nyc node <file> invocation.
  2. Retire the conf if e2e coverage collection is no longer wanted.

This is unrelated to the FKITDEV-8387 entrypoint work and warrants its own YouTrack ticket.

For Agents

For coverage over a codebase that loads .ts on plain Node with no build step (see typescript-in-vuer-repos), reach for c8, not nyc. Any nyc-based coverage in these repos is suspect the moment a .ts require is on the load path.