Why does TypeScript resolve types to a `types/index.d.ts` file when `moduleResolution` is `"node"`?
20:07 11 Nov 2025

The VueX npm package has an exports property in its package.json like this:

  "main": "dist/vuex.cjs.js",
  "exports": {
    ".": {
      "module": "./dist/vuex.esm-bundler.js",
      "require": "./dist/vuex.cjs.js",
      "import": "./dist/vuex.mjs"
    },
    "./*": "./*",
    "./": "./"
  },

And the installed package has a file structure like this:

/vuex
   /dist
      vuex.cjs.js
      vuex.esm-browser.js
      vuex.esm-bundler.js
      vuex.global.js
      vuex.mjs
   /types
      index.d.ts
      helpers.d.ts
      logger.d.ts
      vue.d.ts

The package is not correctly configured for types when moduleResolution is "bundler".

This is documented in issues here #2223 and here #2213 and there is an open PR #2224 that fixes it by adding:

  "main": "dist/vuex.cjs.js",
  "exports": {
    ".": {
      "module": "./dist/vuex.esm-bundler.js",
      "require": "./dist/vuex.cjs.js",
      "import": "./dist/vuex.mjs"
+.    "types": "./types/index.d.ts"
    },
    "./*": "./*",
    "./": "./"
  },

My question does not relate to solving this particular issue, but I did notice something interesting.

If I have a project with

    "module": "es2022",
    "moduleResolution": "node",

Then some code like

import { useStore } from "vuex";

Will resolve the typings to types/index.d.ts correctly.

Whereas if my configuration is

    "module": "nodenext",
    "moduleResolution": "nodenext",
    "module": "esnext",
    "moduleResolution": "bundler",

The typings can not be resolved.

Two questions:

  1. Why does TypeScript allow the mismatch between the module and moduleResolution options when moduleResolution is node?
    "module": "esnext",
    "moduleResolution": "nodenext",

Is not allowed, for example.

  1. Why/how is it that TypeScript can somehow gets that dist/index.ts type?

Reproduction

node.js typescript node-modules