Three Ways to Provide (TypeScript) Type Definitions to Open-Source Libraries
Even though the library of type definitions is vast, the amount of JavaScript libraries is even greater. Every TypeScript developer will encounter a situation where the type definition is missing, or it is not up-to-date. There are four options to deal the situation. One of the options is to live with the fact that there is no auto-completion for the API and you could potentially give the wrong type of arguments to the library. If that option is skipped, then there are three ways to benefit from the TypeScript's powerful type system.
Overview
The described three options are listed in a preferred order (with some catches, more on those later). The preferred order comes from the convenience of obtaining the type definitions and keeping them sync with the changes in the library. The three options are: convert the library to TypeScript, add type definition to the 3rd party library or add the type definition to the Definitely Typed repository.
Convert the library to the TypeScript
Some might think that I am mad to even add this to the list, but this is actually something to consider when you notice that the library is lacking type definitions. It could be that the author of the library has considered TypeScript, for example, when I asked if there is ongoing progress to provide type definitions for the Reactabular library.
Nope. Nobody has contributed those yet. It would be better to port it to TypeScript gradually but that needs a sponsor or contributor.— Juho Vepsäläinen (@bebraw) July 21, 2017
Embedded JavaScript
TypeScript is a superset of JavaScript, so in other words, every JavaScript project is compatible with TypeScript. The beauty is that the types can be added step by step to the library, starting from the API of the library and then going deeper to the internal functions.
Pros
- the library and types are always sync
- no external files, types are defined in place
Cons
- needs changes to the build step
- maintainers must adopt TypeScript which might be unlikely, but worth asking
Add type definitions to the project
Understandably not every project maintainer is interested in TypeScript. The next option is to provide type definition file to the project itself.
The package.json file has a property called types that can be used to point to the correct file ending .d.ts. If the file is in the project root and is named index.d.ts then there is no need to modify package.json.
The difference to the previous method is that the type definitions are defined in an external file instead of in the actual source code of the library.
Pros
- (in theory) the library version and type definitions match as those come from the same source
- pull requests are checked faster as the core maintainers of the library are well-aware of the changes to the library
Cons
- not all project maintainers want TypeScript definitions in their project as they need to verify the pull requests and therefore understand TypeScript
Add type definitions to the Definitely Typed
If all previous methods haven't provided success then there is the last option, add type definition to the central type repository called Definitely Typed. It is a single repository in the GitHub that contains thousands (3484 libraries as I am writing this) of 3rd party library/framework type definitions.
The questions arises, how the single repository approach can work and how the developer can load only requested library's information without loading all type definitions for all supported libraries?
I use the following scenario as an example: the developer sees that graph library has new configuration option, but the library's type definition file doesn't have the change.
Everything starts by reading the Definitely Typed section on editing existing definitions.
When the developer has made changes and tested them according to the instructions, it is time to make a pull request to the repository. The pull request receives automatically a comment that has a checklist of steps that ensure good quality type definition changes.
There are bots that add labels, notify people that are related to this type definition, etc.
After the review process, the pull request gets merged to the master.
The next step is interesting as it is the key to having a loadable type definition. By loadable, I mean that the developer can add the type definitions as a dependency to the package.json file.
Microsoft has built a service called types-publisher that adds each library as a node package to the npm (node package manager). There is a separate organization @types that contains the type definitions. The organization structure allows types to have the same name as the library itself, for example, react-modal is a library, and its type definitions are in the @types/react-modal.
Summary
I highly encourage everyone to contribute and create type definitions. There are many benefits of doing so. You, as a developer will get improved productivity when having auto-completion and also your project benefits from more stable software. Writing type definitions will make you a better developer as you need to read other people's code and describe the API contract in detail. You also learn a lot of TypeScript techniques as some of the APIs require using features of the type system that you might not be familiar with, such as generics, union types, etc.
If you have any questions or comments, let's discuss on Hacker News!