You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
esModuleInterop should work even when compiling to esnext modules #22851
importfn1from'external';// error TS1192: Module '"external"' has no default export.importfn2= require('external');// error TS1202: Import assignment cannot be used when targeting ECMAScript modules.
But, if you use commonjs modules:
tsc --esModuleInterop --module commonjs
It works as expected (because of --esModuleInterop)
importfn1from'external';// worksimportfn2= require('external');// works
Expected behavior:
It is understandable that the type checker doesn't want to pretend the import is interop'd when it's not compiling in the helpers.
But if you've specified --esModuleInterop and --module esnext the assumption from the type checker should be that an external system is applying the interop. Otherwise why would you specify --esModuleInterop?
The question is really about what exactly to emit. When you want to emit to ES modules, a default import really needs to continue being a default import. So esModuleInterop is both about the type-checking as well as the default.
On the other hand, when you expect an external tool (e.g. Babel, Webpack, SystemJS) to stitch the ES interop on its own, that's when you can use allowSyntheticDefaultImports.
I guess you could make the argument that esModuleInterop should imply allowSyntheticDefaultImports and just emit nothing, but Wesley Wigham (@weswigham) might have better insight.
The problem with --allowSyntheticDefaultImports is that it'd still treat import * as foo from 'cjs' the same as import foo from 'cjs'. The ideal behavior would be something like "--requireSyntheticDefaultImports".
Emit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImportsfor typesystem compatibility.
Reacted by Haoqun Jiang, Kunlong Xu, Qing Wang, the L, ExE Boss and Mikhail
allowSyntheticDefaultImports does not fix the issue. It also has broken behaviour when you re-export something that was imported with it: You get an object with the shape { default: T } instead of T
Hi, Just checking is this issue has been resolved? I am facing a similar as was raised by Jamie Kyle (@jamiebuilds)here
I am using a library that is exporting a function as default. While importing I get two different object representation of the imported object based on whether my typescript project is setup as esm or commonjs.
Activity
DanielRosenwasser commentedon Mar 24, 2018
The question is really about what exactly to emit. When you want to emit to ES modules, a default import really needs to continue being a default import. So
esModuleInteropis both about the type-checking as well as the default.On the other hand, when you expect an external tool (e.g. Babel, Webpack, SystemJS) to stitch the ES interop on its own, that's when you can use
allowSyntheticDefaultImports.I guess you could make the argument that
esModuleInteropshould implyallowSyntheticDefaultImportsand just emit nothing, but Wesley Wigham (@weswigham) might have better insight.Jessidhia commentedon Mar 27, 2018
The problem with
--allowSyntheticDefaultImportsis that it'd still treatimport * as foo from 'cjs'the same asimport foo from 'cjs'. The ideal behavior would be something like "--requireSyntheticDefaultImports".aryzing commentedon Apr 8, 2018
Daniel Rosenwasser (@DanielRosenwasser) Doesn't it already? From
--esModuleInteropdocsEmit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImportsfor typesystem compatibility.
jamiebuilds commentedon Apr 9, 2018
allowSyntheticDefaultImportsdoes not fix the issue. It also has broken behaviour when you re-export something that was imported with it: You get an object with the shape{ default: T }instead ofTExE-Boss commentedon Jan 31, 2020
Do note that Node 12.x only supports the
defaultimport whenimporting CommonJS modules from ESModules:This doesn’t work:
The only exception to that are built‑in modules, which have special handling.
teppeis commentedon Jan 26, 2021
This issue seems to have been resolved in TypeScript
3.23.1 or later.bhvngt commentedon Aug 12, 2021
Hi, Just checking is this issue has been resolved? I am facing a similar as was raised by Jamie Kyle (@jamiebuilds) here
I am using a library that is exporting a function as
default. While importing I get two different object representation of the imported object based on whether my typescript project is setup asesmorcommonjs.Project sandbox can be found here.
TS Project setup as commonjs
"type": "commonjs"inpackage.json"module": "commonjs"intsconfig.jsonnode -r ts-node/register src/index.ts[Function: standaloneCode]as output which is the expected outputTS Project setup as esm
"type": "module"inpackage.json"module": "esnext"intsconfig.jsonnode --loader ts-node/esm src/index.ts{ default: [Function: standaloneCode] }. This messes up my type definitions.I have tried with
"esModuleInterop": trueand"allowSyntheticDefaultImports": true. But that does not seem to be making much of a difference.Any workaround or suggestion will be very much appreciated.
teppeis commentedon Aug 27, 2021
const_var (@bhvngt) Your problem is different from this issue. It is the current TypeScript specification.
ajv's
mainhas a special hack that makes it readable from both TS commonjs and esm,https://github.com/ajv-validator/ajv/blob/8ffe5faca9c4b49fc538b35399a1b4febba0bc41/lib/ajv.ts#L34-L35
but your
ajv/dist/standalone/index.jsdoesn't have such a hack.https://github.com/ajv-validator/ajv/blob/8ffe5faca9c4b49fc538b35399a1b4febba0bc41/lib/standalone/index.ts
bhvngt commentedon Aug 27, 2021
Thanks Teppei Sato (@teppeis). Got it. Will raise this issue in
ajvrepo.