Summarized
Your attempt to utilize victor
as if it were an ECMAScript 6 module is incorrect. Two possible solutions are:
Have tsc
transform your modules to a format like commonjs
, which will handle the necessary connection between victor
and your code.
Alternatively, load your application through a module loader that can provide the required integration.
Explanatory Details
With the import you've specified, running the latest version of tsc
yields the error:
This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.
Enabling esModuleInterop
resolves this issue. Check out the test code I employed:
import Victor from "victor";
const foo = new Victor(1, 2);
console.log(foo.y);
Here's the corresponding tsconfig.json
:
{
"compilerOptions": {
"esModuleInterop": true
}
}
The problem stems from the fact that when using import Victor from "victor"
, you're requesting the value exported through an export default...
statement based on ES6 modules syntax. However, no such equivalent exists in victor
. Hence, there needs to be something to bridge the gap. Upon compilation, tsc
generates the following code snippet:
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var victor_1 = __importDefault(require("victor"));
var foo = new victor_1["default"](1, 2);
console.log(foo.y);
An essential point to note here is the __importDefault
helper function that addresses how TS accesses what a module exports as export default...
. For ES6 modules, this process favors correctly structured defaults, while for non-ES6 modules, the helper creates a pseudo-module with the original module's default export.
When targeting ECMAScript modules with this tsconfig.json
:
{
"compilerOptions": {
"esModuleInterop": true,
"module": "es6"
}
}
The resulting emitted code becomes:
import Victor from "victor";
var foo = new Victor(1, 2);
console.log(foo.y);
Omitting the helper function implies reliance on the module loader to replicate the logic integrated by __importDefault
. Renaming the file extension to mjs
and executing:
$ node --experimental-modules test.mjs
Returns the output:
(node:18394) ExperimentalWarning: The ESM module loader is experimental.
2
In situations involving Node with experimental module support, similar functionality akin to __importDefault
is provided.
Mere usage of allowSyntheticDefaultImports
sans esModuleInterop
shifts the responsibility onto you to ensure another tool within your toolchain fulfills the duties of __importDefault
. Compiler offers no assistance in this scenario and lets you progress under the assumption that the task will be handled elsewhere.