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 inpm run buildto invoketscto build the project successfully.npm run testto invokejest+ts-jestto 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.