Skip to content

ESM-only packages come with synthesized default in moduleResolution: bundlerΒ #54752

Description

Bug Report

πŸ”Ž Search Terms

module resolution bundler synthesized default

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// @moduleResolution: bundler
// @module: esnext
// @target: esnext

import mdast, { toString } from "mdast-util-to-string"; // types: 3.2.0

mdast.toString
toString

const mdast2 = await import("mdast-util-to-string"); // types: 3.2.0

mdast2.default
mdast2.default.toString
mdast2.toString

export {}

πŸ™ Actual behavior

default export is available here and points to the whole module. I don't think this is right, even with moduleResolution: bundler but I can be wrong about this since it's really hard to know what kind of assumptions and goals this mode has when it comes to subtle details

πŸ™‚ Expected behavior

I don't expect default to be available here since this ESM-only package doesn't have a default export.

Note that even if this isn't a bug, .default available on that dynamically imported binding should behave in the same way in the IDE as the specifier coming from the import statement. Right now the hover info isn't available on it and go to (type?) definition doesn't work on it with cmd+click.

cc Andrew Branch (@andrewbranch)

Activity

  1. andrewbranch commented on Jun 23, 2023

    @andrewbranch
    Member

    In my view this is part of #54102. The whole schtick is we have no idea that CJS and ESM are even different things outside of moduleResolution: node16. So my plan for #54102 is actually two separate things that go together:

    • We need a different or expanded trigger for making ESM vs CJS determinations in the first place.
    • We need different controls for how that determination affects stuff. Currently it affects both the module resolution algorithm and ESM->CJS default import checking 100% of the time. Those need to be separable, and based on the results we see in https://andrewbranch.github.io/interop-test/, the latter may need to be separately controllable.
  2. andrewbranch commented on Jun 23, 2023

    @andrewbranch
    Member

    Also, moduleResolution isn’t supposed to control anything except what file a module specifier resolves to, but right now, moduleResolution is what triggers the ESM/CJS format determination. A big part of why I did #54567 was to make it so I can switch that without it directly breaking anyone.

  3. Andarist commented on Jun 23, 2023

    @Andarist
    ContributorAuthor

    There is something broken here when it comes to how .default's symbol is not working properly in the IDE, right?

  4. andrewbranch commented on Jun 23, 2023

    @andrewbranch
    Member

    Yeah, I’m sure the default import of a synthesized symbol on a top-level import declaration is special-cased in getSymbolAtLocation / go-to-definition.

  5. typescript-bot commented on Jun 26, 2023

    @typescript-bot
    Contributor

    This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  6. added
    BugA bug in TypeScript
    and removed
    DuplicateAn existing issue was already created
    on Jan 10, 2024
  7. changed the title [-]ESM-only packages come with synthesized default in `moduleReoslution: bundler`[/-] [+]ESM-only packages come with synthesized default in `moduleResolution: bundler`[/+] on Mar 4, 2024
  8. andrewbranch commented on Jun 17, 2024

    @andrewbranch
    Member

    This was backed out of 5.5β€”hoping to reintroduce a fix in 5.6 via #58825.

  9. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions