Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constructor error (TS2351) in TypeScript when using ESM since v5 #81

Open
abouvier opened this issue Nov 1, 2024 · 4 comments
Open

Comments

@abouvier
Copy link

abouvier commented Nov 1, 2024

package.json

{
  "type": "module",
  "dependencies": {
    "fraction.js": "^5.1.0"
  },
  "devDependencies": {
    "typescript": "^5.6.3"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "node16"
  }
}

test.ts

import Fraction from "fraction.js";

let x = new Fraction(1.88);

Compilation error:

$ npx tsc
test.ts:3:13 - error TS2351: This expression is not constructable.
  Type 'typeof import(".../node_modules/fraction.js/fraction")' has no construct signatures.

3 let x = new Fraction(1.88);
              ~~~~~~~~


Found 1 error in test.ts:3

It worked fine in v4, and it works again if "type": "module" is added back to node_modules/fraction.js/package.json.

@infusion
Copy link
Collaborator

infusion commented Nov 1, 2024

What is your current nodejs version? For me it worked providing just the TS definition file. From v4 to v5 the environment setup was changed to work on all major platforms. The "type": "module" is something that makes a module a 100% ESM module, which breaks all older installations. Does it work with a named export?

import {Fraction} from "fraction.js";

@abouvier
Copy link
Author

abouvier commented Nov 1, 2024

What is your current nodejs version?

I tested with nodejs version 22.9.0 and 23.1.0.

Does it work with a named export?

Nope:

$ npx tsc
test.ts:1:9 - error TS2614: Module '"fraction.js"' has no exported member 'Fraction'. Did you mean to use 'import Fraction from "fraction.js"' instead?

1 import {Fraction} from "fraction.js";
          ~~~~~~~~


Found 1 error in test.ts:1

By removing default on the line export default class Fraction { in node_modules/fraction.js/fraction.d.ts then it works with import {Fraction} from "fraction.js";

@infusion
Copy link
Collaborator

infusion commented Nov 1, 2024

That's an interesting insight, thanks! I tested it again and again with nodejs from v16 to v23 and never had a problem. However, since your hint is very valuable, I updated the .d.ts file to support named and default export, same as the ESM export. Hope that also fixes your issue!

@abouvier
Copy link
Author

abouvier commented Nov 2, 2024

That's an interesting insight, thanks! I tested it again and again with nodejs from v16 to v23 and never had a problem. However, since your hint is very valuable, I updated the .d.ts file to support named and default export, same as the ESM export. Hope that also fixes your issue!

Yes now import {Fraction} from "fraction.js"; is working, but the default still not.

It works though if fraction.d.ts is renamed to fraction.d.mts (and the name updated in package.json).
As explained here, each file extension should reflect the type of module used in the file, because without "type": "module" in package.json then fraction.d.ts is considered a CommonJS file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants