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
"moduleResolution": "NodeNext" throws ESM related errors #50058
Comments
It sounds like you had a misconfiguration and fixed it. I don't see a demonstrated bug here. |
Isn't |
Yes, that's what the issue is here. When |
@fatcerberus points out that #50086 is likely related FWIW. |
@sheetalkamat was this also fixed by your PR? |
It probably is but i didnt verify it explicitly (assuming issue is with descipencies between errors reported for vscode and tsc) |
The main issue with ESM and The officially proposed workaround is to manually add It's particularly surprising because TypeScript encourages you to use Frontend framework users whose build toolchain compiles TypeScript on demand will be hit next as they add the It makes my team members develop an aversion to TypeScript, not to mention it probably got me looking pretty bad myself, because the only way to perform the otherwise trivial act of delivering an isomorphic library (i.e. one which which works out of the box in all contexts - Node, browser, ESM, CJS, pre-compiled, on-demand, framework, no framework) is walking the compiled code's AST to add the extensions. |
I am seeing an issue similar to this where the addition of Basically, when trying to import the
Despite the fact that I created a super simple repro repo (reprository?) here: https://github.com/smaye81/ts-repro. You can see this behavior by running the two scripts:
I'm not sure if I'm just using a bad configuration, but I would think at the very least this error message should be fixed, right? |
Not sure if same issue but with Basically this code won't work w
My current workaround is to add dozens of lines such as
Makes the editor code go away but now code doesn't transpile correctly (results in things like ajv['default']['default']) What is baffling is IF editor says error then its correct and if it says no error then its not. I kept thinking that my TS linter and my |
I encountered this similar problem when I want to import the default this doesn't workimport create from "zustand/vanilla";
export const store = create(() => ({ foo: "bar" })); this worksimport zustand from "zustand/vanilla";
import { defaultImport } from "default-import";
const create = defaultImport(zustand);
export const store = create(() => ({ foo: "bar" })); A minimal repo to reproduce this problem: https://stackblitz.com/edit/node-vj368k?file=src/index.ts |
|
@weswigham Thanks for the quick response, so what's the correct way to declare types for a mjs entrypoint? Forgive me if I sound stupid. Update: There're generally two things that worth noting:
|
I’m facing the same issue in these two PRs:
Here are some third-party packages that have problems with default exports when
As a temp solution, I’ve managed to do this: -import x from "x";
+import _x from "x";
+const x = _x as unknown as typeof _x.default; Although it‘s true that the problem is within the packages, I wonder if it is possible to create a new compile option which could be used during the transition period? Something like When switching a project to |
I would also add |
Thanks @RyanCavanaugh! Yep, you are right – the problem is with incorrect upstream typings. In an ideal world, the ecosystem would be ESM-ready and we would not have this problem at all. In practice, we have quite a few npm packages that won't be quick to patch, which complicates the migration to This specific |
|
Looking at the comparison table between The only problem with |
Maybe I'm a bit confused on what your actual runtime environment is. If it's actually Node 16+, then this code legitimately does not work and the
It's going to be a nightmare if this flag gets common usage, because every single day someone will see a module declaration that says export default function() { }
export function foo() { }; import it with // OK, good
import { foo } from "my-module";
foo();
// Fails, TypeScript is clearly broken beyond repair,
// this is obviously a bug
import theFunction from "my-module";
theFunction(); Maybe if it's named Certainly there are going to be modules which don't have top-level function behavior and thus aren't particularly affected, but I'd argue this actually makes the situation worse, since it effectively 100% hides a configuration error. In the future I think someone might reasonably ask for a The community wouldn't catch up because they wouldn't even realize they're behind. |
Ryan and I have investigated two specific instances of this double-default problem in the last two days. One was ajv; the other was react-use-websocket. Both had users reporting that after default-importing the library, they had to access Now for the differences. ajv’s JS uses this pattern: module.exports = exports = Ajv;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = Ajv; which means the import Ajv from "ajv";
Ajv; // Actually [class Ajv], but TypeScript thinks { default: [class Ajv] }
Ajv.default; // [class Ajv], Node and TypeScript agree!
Ajv.default.default // Still [class Ajv], TypeScript doesn't know this exists So, the typings aren’t exactly wrong, they’re just incomplete in a rather painful way. In this case, because of the interop strategy present in ajv’s JS, the sort of flag @kachkaev suggested would be safe to use. react-use-websocket, on the other hand, only has this in their JS: Object.defineProperty(exports, "__esModule", { value: true });
// ...
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return use_websocket_1.useWebSocket; } });
import useWebSocket from "react-use-websocket";
useWebSocket; // { default: [Function: useWebSocket] } Node and TypeScript agree!
useWebSocket.default; // [Function: useWebSocket] Node and TypeScript agree! Here, the types are exactly right! Obviously, the author of react-use-websocket didn’t anticipate this function being loaded under Node’s ESM interop algorithm (and probably with good reason, since it’s intended for front-end use), but that’s a bit beside the point. A flag that pairs this The problem is that we can’t tell the difference between these two cases without inspecting the actual JavaScript, which would completely defeat the point of having declaration files in the first place, and be very costly in terms of memory and compile time. Like Ryan, I’m sympathetic to this problem, but I 100% believe that if we added a flag to enable this kind of loose behavior, everyone would turn it on, library authors would use it as an excuse not to fix their definitions, and we’d never be able to remove it and fix the source of the problem. |
Fix the issue that `@kosko/env` cannot be resolved correctly when `moduleResolution=nodenext` is set in `tsconfig.json`. microsoft/TypeScript#50058
Fix the issue that `@kosko/env` cannot be resolved correctly when `moduleResolution=nodenext` is set in `tsconfig.json`. microsoft/TypeScript#50058
Leaving a note for the users of these two libraries as they seem to trigger this kind of error too with Sample code:
The errors:
|
This kind of error pretty much always indicates that the types use I guess big.js is on DefinitelyTyped but probably has the same problem. Will take a look at that next. Edit: big.js fix is up DefinitelyTyped/DefinitelyTyped#66163 |
I have same problem for module
EDIT : I found how to fix. You have to do this : import type { Functions } from 'serverless/aws.d.ts'; |
Does this issue occur when all extensions are disabled?: Yes
Steps to Reproduce:
npm
package. Installtypescript@4.7.4
andpretty-ms
.tsconfig.json
as:"type": "module"
inpackage.json
.ts
extension undersrc/
:tsc
throws no errors.tsconfig.json
The text was updated successfully, but these errors were encountered: