Search code examples
typescriptnpmtscnpm-package.d.ts

How to bundle many TypeScript declaration files into an npm package and import from index.d.ts?


I have an internal package with about the following structure:

myPackage/
|- types/
|  |- type1.d.ts
|  |- type2.d.ts
|- src/
|  |- someUtilities.ts
|- index.ts
|- package.json
|- tsconfig.json

The index.ts is importing and exporting all the .d.ts files in ./types and all the .ts files in ./src. I transpile it with tsc and copy all the declaration files into the build and get this structure.

myPackage/
|- types/
|  |- type1.d.ts
|  |- type2.d.ts
|- src/
|  |- someUtilities.ts
|- index.d.ts
|- index.js
|- package.json

The index.d.ts is correctly having all the type imports and exports as is expected and index.js has the transpiled version of whatever I have in the src. So far all good.

I have another (CRA) project where I want to use this internal package. I pack myPackage and then in that other project I put into package.json with

dependencies: {
  "myPackage": "file:pathToMyPackage.tgz"
}

During development VSCode finds all the types and functions correctly from the package. However when I run npm run build, which is simply running react-scripts build, I get an error Module not found: Can't resolve './types/type1.d.ts' in '/node_modules/myPackage.

If I create an index file under the types directory and point that as my types in package.json, the build process will find those types, but obviously can't find the transpiled types from the src files.

myPackage/
|- types/
|  |- type1.d.ts
|  |- type2.d.ts
|  |- index.d.ts <- this one importing those above and works in when using as dep in other projects
|- src/
|  |- someUtilities.ts
|- index.d.ts <- this isn't found because package.json points to types/index.d.ts as types
|- index.js
|- package.json

I then tried using one single index at the package root and used those triple slash directives to point to the types. That sort of works, but then at other projects I have to use the full path to a certain type when importing it

// index.ts at package root
/// <reference path="./types/type1.d.ts">
/// <reference path="./types/type1.d.ts">
import { someUtility } from './src/someUtilities'
export { someUtility }
// Doesn't work
import { someType } from 'myPackage'

// Works
import { someType } from 'myPackage/path/to/the/type/file'

Is it possible to separate all the types into their separate files and bundle them somehow, so that they can be imported from the index or do I need to manually bundle them into a huge index.d.ts file and just use from there? I wouldn't like to do that, because that index declaration file would be huge and hard to manage. I have multiple declaration files under the types directory and each of them is their own namespace.


Solution

  • I figured it out that in order to have all the .ts and .d.ts files in one entry point the .d.ts types need to be imported as import { type someType } from './types/type1.d.ts'

    So the index.ts file in the root could be something like this:

    export { utility } from './src/someUtilities'
    export { type someType } from './types/type1'
    

    Now when that is transpiled all the imports and exports are correctly in the generated index.d.ts file in the root. Of course the .d.ts files you have created outside the transpiling process need to be copied into the types folder.