Skip to content

.cts files use ESM mode for module resolution #51737

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

Closed
IanVS opened this issue Dec 3, 2022 · 2 comments
Closed

.cts files use ESM mode for module resolution #51737

IanVS opened this issue Dec 3, 2022 · 2 comments
Assignees
Labels
External Relates to another program, environment, or user action which we cannot control.

Comments

@IanVS
Copy link

IanVS commented Dec 3, 2022

Bug Report

🔎 Search Terms

"Resolving in ESM mode", ".cts", "NodeNext"

🕗 Version & Regression Information

  • This is the behavior in every version I tried (4.7 - 5.0 nightly), and I reviewed the FAQ for entries about ".cts", "module resolution"

⏯ Playground Link

I tried to use the playground and the bug-workbench, but wasn't able to get it to emit type declaration files. This is a minimal reproduction I created to clearly show the issue:

https://github.com/IanVS/mts-cts-reproduction

💻 Code

Here's my attempt at the bug workshop, but I suggest checking out my repo above instead.

// @moduleResolution: Node16

// @filename: node_modules/exports/package.json
{
  "name": "exports",
  "type": "module",
  "exports": {
    ".": {
      "import": {
        "types": "./index.d.ts",
        "default": "./index.js"
      },
      "require": {
        "types": "./index.d.cts",
        "default": "./index.cjs"
      }
    },
    "./package.json": "./package.json"
  }
}

// @filename: node_modules/exports/index.d.ts
export declare const value: "esm";

// @filename: node_modules/exports/index.d.cts
export declare const value: "cjs";

// @filename: package.json
{
  "name": "mts-cts-repro",
  "type": "module",
}

// @filename: src/foo.cts
export async function Foo() {
  return (await import("exports")).value;
}

// @filename: src/foo.mts
export async function Foo() {
  return (await import("exports")).value;
}

// @filename: src/foo.d.cts
// --- WHY IS THIS "esm"?---
export declare function Foo(): Promise<"esm">;

// @filename: src/foo.d.mts
export declare function Foo(): Promise<"esm">;

Workbench Repro

🙁 Actual behavior

.cts files are using the import condition, and getting esm types instead of the commonjs types from a node_module package defining "exports".

Even stranger, in VSCode, intellisense is showing "cjs" as the type for (await import("exports")).value in both the .cts and the .mts file, which is the opposite behavior from tsc, which treats them both as "esm".

🙂 Expected behavior

I expected .cts files to use the "require" condition by default (unless modified by the new resolution-mode, available only in nightly).

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Dec 7, 2022
@weswigham
Copy link
Member

Dynamic import always follows esm resolution rules in node - you'll find the esm file is loaded at runtime, too.

@weswigham weswigham added External Relates to another program, environment, or user action which we cannot control. and removed Needs Investigation This issue needs a team member to investigate its status. labels Dec 8, 2022
@IanVS
Copy link
Author

IanVS commented Dec 8, 2022

Thank you, is this documented anywhere in the TypeScript docs? I couldn't find it when I looked, and could submit a PR if desired.

Also, for the problem in the VSCode intellisense, where should I raise an issue for that? Would that be a TypeScript issue, or a VSCode issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External Relates to another program, environment, or user action which we cannot control.
Projects
None yet
Development

No branches or pull requests

3 participants