DEV Community

Cover image for How to generate Type Definitions for Distribution on NPM
David MacEachern
David MacEachern

Posted on

How to generate Type Definitions for Distribution on NPM

tl;dr

  • If in doubt create a toy application quickly using a project template, for Typescript this could be done using tsdx
  • A checklist of the things required to test from the point of view of the end user might be helpful, how will they consume the library in the end?
  • It always helps to scroll through the docs to understand what the tools we are working with can do, to solve the problems I encountered whilst writing this I visited, tsc, babel, and npm.

Problem

I was recently testing out a web application, and in doing so I created a toy application and imported a small open-source library I had created.

# main.ts
import { Nosozu } from 'nosozu';
Enter fullscreen mode Exit fullscreen mode

VS Code started giving me an error related to missing type definitions, despite having installed the package using npm before using npm i nosozu.

Cannot find module '@nosozu' or its corresponding type declarations.
Enter fullscreen mode Exit fullscreen mode

What I did to generate type definitions

In the tsconfig.json I added the field which tells the Typescript compiler to generate the type definition.

{
+  "declaration": true,
Enter fullscreen mode Exit fullscreen mode

In the package.json I checked what was declared as the main entry point to the library, and then added a line for where the types will be located.

  "main": "dist/index.js",
+ "types": "dist/index.d.ts",
Enter fullscreen mode Exit fullscreen mode

Tidying up the NPM Package

Checking the first version I published of Nosozu, the user would install our package using npm i nosozu@2.0.1-alpha, in doing so and checking what files are in ./node_modules/nosozu/ they would find 49 files totaling 63.6 kB.

Taking a look at other node_module directories within the project, helped to understand what files are generally included when publishing a library like this.

Then also reading about what the .npmignore file is for over here helped in figuring out how to exclude sending things like test and example folders to npm.

I then settled with adding the following allowed list to the package.json

+  "files": [
+    "/dist"
+  ]
Enter fullscreen mode Exit fullscreen mode

This led to a node_modules directory structure like:

.
|-- node_modules
|   |-- nosozu
|   |   |-- LICENSE
|   |   |-- README.MD
|   |   |-- package.json
|   |   |-- CHANGELOG.md
|   |   |-- dist 
|   |   |   |-- command-builder.d.ts
|   |   |   |-- command-builder.js
|   |   |   |-- error.d.ts
|   |   |   |-- error.js
|   |   |   |-- index.d.ts
|   |   |   |-- index.js
|   |   |   |-- json-client.d.ts
|   |   |   |-- json-client.js
|   |   |   |-- protocol.d.ts
|   |   |   |-- protocol.js
Enter fullscreen mode Exit fullscreen mode

Testing the changes worked before publishing the fix

Before publishing the new version I checked whether these changes fixed the original import issue. I did so by copying the contents of the dist folder and the package.json into the node_modules/nosozu of the project I was testing in the beginning.

In Bash this looked something like:

cd playground-timber-nosozu/playground-timber-nosozu/
rm -rf ./node_modules/nosozu/                         # remove the installed library
mkdir ./node_modules/nosozu                           # make the folder again
cp -r ../../nosozu/dist/  ./node_modules/nosozu       # copy the modified library with types
cp ../../nosozu/package.json  ./node_modules/nosozu   # copy package.json so our application can see the "main" and "types" 
Enter fullscreen mode Exit fullscreen mode

This could also be done using npm link.

The changes to that project can be seen here, I did change the package name before publishing it to NPM, as well as messing around with unpublishing versions on NPM. If you do make mistakes it's possible to undo them but consider if there are any users that this might affect!

Wrapping up

Checking the package again, the size has increased to 123 kB however the number of files has reduced to 15. I reinstalled this in the toy project and found everything appeared to be working, except for an error being thrown inside the library itself, work for another day!

Maybe you want to learn more about Typescript, or maybe you know something I don't!

Contributions of any sort are more than welcome, you can see open issues over here

Top comments (2)

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

I usually put declarationMap: true as well.

Not sure if I need sourceMap for publishing?

Collapse
 
davidmaceachern profile image
David MacEachern • Edited

Great idea.

I checked with VSCode and it can currently right click to 'go to definition' with this configuration, but it goes to the d.ts file. Some other editors might not support this.

Looking at what people might prefer is discussed here... so the source map will probably be helpful.

Thanks for noticing that!