mathjs: TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.

Describe the bug Getting the following error:

tsc --noEmit        
../bla/node_modules/mathjs/types/index.d.ts:5:1 - error TS1203: Export assignment cannot be used when targeting 
ECMAScript modules. Consider using 'export default' or another module format instead.

5 export = math
  ~~~~~~~~~~~~~


Found 1 error in ../balances/node_modules/mathjs/types/index.d.ts:5

To Reproduce I have "type": "module" in my package.json and

"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node16"

in my TSConfig, using TS v5.0.2, it used to work with TS v4.9.5

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 25 (17 by maintainers)

Commits related to this issue

Most upvoted comments

As a temporary workaround until this issue is fixed, one way we were able to solve it was by doing this. We’re suppressing the typescript error, but the types will still show up correctly.

// @ts-expect-error suppress typescript errors until issue is resolved https://github.com/josdejong/mathjs/issues/2919
const mathjs: typeof import('mathjs') = require('mathjs')

This is partly because TypeScript expects you to ship two different .d.ts files, one for cjs, and one for esm.

See: https://www.typescriptlang.org/docs/handbook/esm-node.html#packagejson-exports-imports-and-self-referencing

It’s important to note that the CommonJS entrypoint and the ES module entrypoint each needs its own declaration file, even if the contents are the same between them. Every declaration file is interpreted either as a CommonJS module or as an ES module, based on its file extension and the “type” field of the package.json, and this detected module kind must match the module kind that Node will detect for the corresponding JavaScript file for type checking to be correct. Attempting to use a single .d.ts file to type both an ES module entrypoint and a CommonJS entrypoint will cause TypeScript to think only one of those entrypoints exists, causing compiler errors for users of the package.

As of now, the package.json looks like this:

    ".": {
      "types": "./types/index.d.ts",
      "import": "./lib/esm/index.js",
      "require": "./lib/cjs/index.js"
    },

It should look like this:

    ".": {
      "import": "./lib/esm/index.js",
      "require": "./lib/cjs/index.js"
    },

with the index.d.ts copied into ./lib/esm/ and ./lib/cjs, or:

    ".": {
      "import": {
        "types": "./types/index.d.ts",
        "default": "./lib/esm/index.js"
      }
      "require": {
        "types": "./types/index.d.cts",
        "default": "./lib/cjs/index.js"
      }
    },

with index.d.ts duplicated to index.d.cts.

No other changes are necessary.

I want to program in TypeScript for the browser without bundling.

🤔 hm are you trying to load non-bundled code in the browser? I’m not sure but I guess there are two different issues in play then: one is the export = math issue. And the other is that some of the dependencies are not ES modules, making it currently impossible to load the non-bundled code in a browser, see #1841, #1928. In this issue (#2919) we try to tackle the export = math issue

Good to hear you have a solution for your case. Thanks for your work on solving this!

I’ll close your two PR’s for the time being until someone can pick this up.