helmet is a popular hybrid (cjs + esm) module.
ts-jest resolves import helmet from 'helmet'
to the index.d.cts
artefact, whereas the typescript compiler, when invoked directly, resolves it to the index.d.mts
artefact. Consequently the tsc build succeeds but the ts-jest build fails with the following:
FAIL __test__/index.test.ts
● Test suite failed to run
src/index.ts:4:3 - error TS2349: This expression is not callable.
Type 'typeof import("/node_modules/helmet/index")' has no call signatures.
4 helmet();
npm i
npm run build
to invoketsc
to build the project successfully.npm run test
to invokejest
+ts-jest
to reproduce the failing test compilation.
I'm new to both codebases, but I've been tracing the module resolution locally and found that tsc
and ts-jest
invoke TypeScript's resolveModuleName function differently. tsc
passes ModuleKind.ESNext
as the final moduleResolution
argument whereas ts-jest
does not pass the argument at all.
I'm having some difficulty determining the exact logic that tsc uses to decide the moduleResolution
argument but if I force the moduleResolution
to ESNext
in ts-jest then the tests are built successfully.