How to generate Type Definitions for Distribution on NPM 
Tags: showdev, npm, typescript, javascript
Published: 2020-12-11 13:35:31

## tl;dr

- If in doubt create a toy application quickly using a project template, for Typescript this could be done using [tsdx](https://tsdx.io/)
- 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](https://www.typescriptlang.org/docs/handbook/compiler-options.html), [babel](https://babeljs.io/), and [npm](https://docs.npmjs.com/cli/v6).

## 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';
```

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.
```

## 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.

``` diff
{
+  "declaration": true,
```

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.

``` diff
  "main": "dist/index.js",
+ "types": "dist/index.d.ts",
```

## 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](https://docs.npmjs.com/cli/v6/using-npm/developers#testing-whether-your-npmignore-or-files-config-works) 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

```diff
+  "files": [
+    "/dist"
+  ]
```

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
```

## 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:

```bash
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" 
```

This could also be done using `npm link`.

The changes to that project can be seen [here](https://github.com/davidmaceachern/playground-timber-nosozu/commit/f1b377c0e21c24e570664f9bb07581d2ec4ad94c), 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](https://www.npmjs.com/package/nosozu) 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](https://github.com/davidmaceachern/nosozu/issues)