`esModuleInterop: true` cause runtime error
See original GitHub issueHi there, problems happened when I toggled esModuleInterop
flag for my project, I have to because one library it depends enabled this flag.
TypeScript Version: 2.7+
Search Terms: esModuleInterop allowSyntheticDefaultImports
Code
import * as apmStar from 'elastic-apm-node'
import SentryDefault from '@sentry/node'
apmStar.start // undefined
SentryDefault // undefined
Explains:
- for
@sentry/node
it is an es module, soesModuleInterop
has no effects on it, but withallowSyntheticDefaultImports
you can import its default, which property it does not export, so you got an undefined error at runtime - for
elastic-apm-node
, it is a commonjs module, and it exports an instance,start
is a prototype method of it, so it is lost after__importStar
.
But these problems are not informed in the document, guess we could discourage enabling it for library projects? And I wonder if we could improve type checking for these situations, for example:
- for
apmStar
, it is imported as esmodule namespace, so an type error could be thrown when accessing.start
method on it. - for
SentryDefault
, it is a esmodule,allowSyntheticDefaultImports
could be disabled for it
Expected behavior: Error emitted at compiling time Actual behavior: Compiled successfully, but got an error at runtime.
Playground Link: https://repl.it/@themez1/esModuleInteropTest
Related Issues: https://github.com/microsoft/TypeScript/issues/28009 https://github.com/microsoft/TypeScript/issues/33954 https://github.com/microsoft/TypeScript/issues/36026
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:13 (5 by maintainers)
Top GitHub Comments
We encountered a similar issue in https://github.com/microsoft/rushstack/issues/2526 . The repro is very easy:
1.2.5
in our case)esModuleInterop=true
in tsconfig.json@RyanCavanaugh in our case, setting
allowSyntheticDefaultImports=false
reports an error for the correct import form. So that doesn’t seem to be a solution.Setting
esModuleInterop=true
causes the compiler to silently accept code that will fail at runtime. These bugs may lurk in the code base for a long time until someone hits that code path (and bothers to report it). Maybe something is wrong with the typings for thecolors
package, but we’ve also encountered this with various other popular Node.js packages.What’s the right way to prevent these mistakes? We never had these problems with
esModuleInterop=false
.It’s definitely a guaranteed indicator that the file is a cjs-format module that’s masquerading as an es module and has no default presented by ts/babel’s import helpers.
You shouldn’t put it in the declarations for actually-esm format modules, however, since those don’t use any import helpers 😛