Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript and Subpath Imports

I am trying to get Node subpath imports and typescript to work. My IDE has no problem resolving the imports, but Typescript is never happy.

Github repo with code: https://github.com/doronrosenberg/ts-subpath-imports.

package.json:

  "imports": {
    "#internal/*": "./internal/*.ts",
    "#internal2": "./internal"
  }

tsconfig.json:

  "paths": {
    "#internal/*": "./internal/*.ts",
    "#internal2": ["./internal"]
  }

and the code:

import { foo } from "#internal/index";
import { bar } from "#internal2";

No matter how I set things up, I always get:

src/test.ts:1:21 - error TS2307: Cannot find module '#internal/index' or its corresponding type declarations.

1 import { foo } from "#internal/index";
                      ~~~~~~~~~~~~~~~~~

src/test.ts:2:21 - error TS2307: Cannot find module '#internal2' or its corresponding type declarations.

2 import { bar } from "#internal2";
                      ~~~~~~~~~~~~

Any ideas?

like image 441
user910046 Avatar asked Mar 06 '26 19:03

user910046


2 Answers

After hacking around with Typescript for a few weeks, I got a working solution.

Let's say I have a package called @kodadot1/metasquid with multiple submodules (consolidator and entity).

In my package.json I declare imports

  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    },
    "./consolidator": {
      "types": "./dist/consolidator.d.ts",
      "import": "./dist/consolidator.mjs",
      "require": "./dist/consolidator.cjs"
    },
    "./entity": {
      "types": "./dist/entity.d.ts",
      "import": "./dist/entity.mjs",
      "require": "./dist/entity.cjs"
    }
}

The trick is to create a .d.ts file for each submodule in the project's root.

So for submodule entity I will make a file called entity.d.ts that contains

export * from './dist/entity'

Now to publish it correctly in npmjs extend your package.json like:

  "files": [
    "dist",
    "*.d.ts"
  ]

Now just publish, and you can enjoy subpath imports:

import { get } from '@kodadot1/metasquid/entity'

Whole code is available here

like image 125
vikiival Avatar answered Mar 09 '26 13:03

vikiival


The support of subpath exports requires newer module resolutions such as Node16 and NodeNext:

{
  "compilerOptions": {
    "moduleResolution": "Node16" // or `"NodeNext"`
  }
}
like image 31
unional Avatar answered Mar 09 '26 15:03

unional