tsx
tsx copied to clipboard
The `esModuleInterop` and module importing is inconsistent (and mandatory?) with tsx
Precheck
- [X] I searched existing issues before opening this one to avoid duplicates
- [X] I'm able to reproduce this issue and prove it with a minimal reproduction
- [X] I understand this is not a place to ask for free debugging support
Problem
I have a file
// @ts-ignore
import deepmergeAsDefault from 'deepmerge' // < === BREAKS IN TypeScript, I have esModuleInterop: false
import * as deepmerge from 'deepmerge'
import * as _ from 'lodash'
console.log(_.merge({ lodashA: 1 }, { lodashB: 2 })) // < === WORKS
console.log(deepmergeAsDefault({ deepmergeAsDefaultA: 1 }, { deepmergeAsDefaultB: 2 })) // < === WORKS
console.log(deepmerge({ deepmergeA: 1 }, { deepmergeB: 2 })) // < === BREAKS
I have a // @ts-ignore on top of the default import, since TypeScript complains, rightly so since my esModuleInterop: false (the default):
TS1259: Module
'//wsl.localhost/ubuntara/mnt/projects/devzen-tools/packages/speczen/node_modules/deepmerge/index'
can only be default-imported using the esModuleInterop flag
index.d.ts(20, 1): This module is declared with export = , and can only be used with a default import when using the esModuleInterop flag
When I execute I get:
╰─$ tsx temp/import-without-default-import.ts
{
detail: undefined,
id: 'call-import-namespace',
location: {
column: 12,
file: '/mnt/projects/devzen-tools/packages/speczen/temp/import-without-default-import.ts',
length: 9,
line: 8,
lineText: 'console.log(deepmerge({ deepmergeA: 1 }, { deepmergeB: 2 }))',
namespace: '',
suggestion: ''
},
notes: [
{
location: [Object],
text: 'Consider changing "deepmerge" to a default import instead:'
},
{
location: null,
text: `Make sure to enable TypeScript's "esModuleInterop" setting so that TypeScript's type checker generates an error when you try to do this. You can read more about this setting here: https://www.typescriptlang.org/tsconfig#esModuleInterop`
}
],
pluginName: '',
text: `Calling "deepmerge" will crash at run-time because it's an import namespace object, not a function`
}
{ lodashA: 1, lodashB: 2 }
{ deepmergeAsDefaultA: 1, deepmergeAsDefaultB: 2 }
/mnt/projects/devzen-tools/packages/speczen/temp/import-without-default-import.ts:8
console.log(deepmerge({ deepmergeA: 1 }, { deepmergeB: 2 }))
^
TypeError: deepmerge is not a function
at deepmergeAsDefault (/mnt/projects/devzen-tools/packages/speczen/temp/import-without-default-import.ts:8:13)
at Object.<anonymous> (/mnt/projects/devzen-tools/packages/speczen/temp/import-without-default-import.ts:8:60)
at Module._compile (node:internal/modules/cjs/loader:1241:14)
at Object.j (/home/anodynos/.asdf/installs/nodejs/20.8.0/lib/node_modules/tsx/dist/cjs/index.cjs:1:1197)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Module._load (node:internal/modules/cjs/loader:938:12)
at cjsLoader (node:internal/modules/esm/translators:284:17)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:234:7)
at ModuleJob.run (node:internal/modules/esm/module_job:217:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
Node.js v20.8.0
if you noticed,
{ lodashA: 1, lodashB: 2 }
{ deepmergeAsDefaultA: 1, deepmergeAsDefaultB: 2 }
worked, which is incosistent. I imported lodash normally (for my esModuleInterop: false) and deepmerge in an illegal way for my project, and these are the 2 that worked.
But the legit deepmerge({ deepmergeA: 1 }, { deepmergeB: 2 }) broke.
In ts-node
import * as deepmerge from 'deepmerge'
import * as _ from 'lodash'
work as expected (and the deepmergeAsDefault breaks as should).
All my project is using non-default imports, and I don't want to enable esModuleInterop cause some library was breaking some time ago, and all my project is using the non-esModuleInterop any way and works just fine with all other tooling, including ts-node, jest with ts-jest and as compiled js code.
Is there any flag I'm missing that can accommodate this?
Expected behavior
To work like it does with all other tooling and respecting my ts-config.
Minimal reproduction URL
https://stackblitz.com/edit/node-34fss6?file=index.ts
Version
v3.14.0
Node.js version
20.8.0
Package manager
npm
Operating system
Linux
Contributions
- [ ] I plan to open a pull request for this issue
- [ ] I plan to make a financial contribution to this project