TypeStrong / ts-node

TypeScript execution and REPL for node.js
https://typestrong.org/ts-node
MIT License
12.86k stars 536 forks source link

Compile time errors being suppressed when using esm #2129

Open Stono opened 2 months ago

Stono commented 2 months ago

I really struggled to think of the correct title for this, so please edit it as required. I went down a rabbithole today whilst moving one of our apps to esm, as it was failing to start (with ts-node) due to the following node error:

❯ node --experimental-specifier-resolution=node --loader ts-node/esm lib/index.ts
node:internal/modules/run_main:115
    triggerUncaughtException(
    ^
[Object: null prototype] {
  [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]]
}

Node.js v22.5.1

Doesn't really give away much. It turned out however that the root caused we missed a return type on a promise eg Promise needed to be Promise<void>. This error was visible if you did a tsc, but ts-node was giving this output.

After gradually chipping away at the code to make a minimal example; i managed to reproduce it with a really simple bit of code that doesn't even technically have an error in it.

Assuming your code is in ./lib, create ./lib/index.ts:

import { SomeServer } from './server.js'

const webServer = new SomeServer()

and ./lib/server.ts:

export class SomeServer {}

If you try and start this; you'll get the error. The only thing "wrong" with this code is the fact that webServer is an unused variable. If i add console.log(webServer), eg:

import { SomeServer } from './server.js'

const webServer = new SomeServer()
console.log(webServer)

Then all is well:

❯ node --experimental-specifier-resolution=node --loader ts-node/esm lib/index.ts

SomeServer {}

Specifications