When using the "main" field of package.json for a Typescript NPM package, this documentation explains how to ship your types (as .d.ts files) alongside the payload exported JS file.
package.json also allows multiple entrypoints, multiple js files, to be specified using the "exports" field rather than "main".
But in that case, how should the various .d.ts files of these various entrypoints be specified in package.json ?
You may specify d.ts file separately for each export option. This feature appeared in TS 4.7
Example:
// package.json
{
"name": "my-package",
"type": "module",
"exports": {
".": {
// Entry-point for `import "my-package"` in ESM
"import": {
// Where TypeScript will look.
"types": "./types/esm/index.d.ts",
// Where Node.js will look.
"default": "./esm/index.js"
},
// Entry-point for `require("my-package") in CJS
"require": {
// Where TypeScript will look.
"types": "./types/commonjs/index.d.cts",
// Where Node.js will look.
"default": "./commonjs/index.cjs"
},
}
},
// Fall-back for older versions of TypeScript
"types": "./types/index.d.ts",
// CJS fall-back for older versions of Node.js
"main": "./commonjs/index.cjs"
}
Or some real example. From stylelint package:
"exports": {
".": {
"import": {
"types": "./types/stylelint/index.d.mts",
"default": "./lib/index.mjs"
},
"require": {
"types": "./types/stylelint/index.d.ts",
"default": "./lib/index.cjs"
}
},
"./package.json": "./package.json",
"./lib/utils/*": "./lib/utils/*"
},
"main": "lib/index.cjs",
"types": "types/stylelint/index.d.ts",