dnt icon indicating copy to clipboard operation
dnt copied to clipboard

Types-only .ts files are transformed into .d.ts files that try to import .js files

Open MasterKale opened this issue 1 year ago • 2 comments

I have a package that only imports and exports TypeScript types. It has two files, index.ts and dom.ts, and index.ts relatively imports from dom.ts but not the other way around:

https://github.com/MasterKale/SimpleWebAuthn/tree/master/packages/types

I noticed recently that when my package builds, the types in these two files are being output to ${outDir}/types/ as .d.ts as expected...

Screenshot 2024-04-12 at 11 56 33 AM

...and declared in package.json as expected:

"exports": {
  ".": {
    "import": {
      "types": "./types/index.d.ts",
      "default": "./esm/index.js"
    },
    "require": {
      "types": "./types/index.d.ts",
      "default": "./script/index.js"
    }
  }
}

However when I open up ${outDir}/types/index.d.ts I see that the import type and export type statements are transformed by dnt to import from "./dom.js":

Screenshot 2024-04-12 at 11 58 56 AM

This is breaking the ability to Go To Definition on a type contained in dom.ts in libraries installing this package from NPM. I tried using mappings to replace the path, but as this isn't really what mappings is intended for of course it didn't work.

MasterKale avatar Apr 12 '24 19:04 MasterKale

I'm hitting the same issue.

igorgatis avatar Feb 06 '25 03:02 igorgatis

Here is a workaround:

  postBuild: async () => {
    async function processDirectory(dirPath: string) {
      console.log("[dnt] Fixing imports under", dirPath);
      for await (const entry of Deno.readDir(dirPath)) {
        const fullPath = `${dirPath}/${entry.name}`;
        if (entry.isDirectory) {
          await processDirectory(fullPath);
        } else if (entry.isFile && entry.name.endsWith(".d.ts")) {
          const content = await Deno.readTextFile(fullPath);
          const updatedContent = content.replace(/\.js"/g, '.d.ts"');
          await Deno.writeTextFile(fullPath, updatedContent);
        }
      }
    }
    await processDirectory("./npm/types"); // Provide required path here.
  },

igorgatis avatar Feb 06 '25 03:02 igorgatis