typescript_for_public_apis

MIT License

Stars
6

Using TypeScript for Public APIs in vanilla JS projects.

TLDR: skip to the Suggested Pattern

Background

In the article Get the advantages of TypeScript without transpiling @segphault described how TypeScript and JSDocs annotations can be combined to provide type checking capabilities for vanilla JavaScript projects.

This repo takes this concept one step farther and demonstrates how to use TypeScript to provide validated high quality public APIs in a vanilla JavaScript project.

Can't we already do this using DefinitelyTyped?

DefinitelyTyped is awesome as it allows "external" contributors to provide definitions for packages independently of the "internal" development of these packages.

This approach however, has three main disadvantages:

  1. Independent life cycle of packages and their definitions may lead to quality issues.
  2. Definitions developed by end users instead of package authors may suffer from quality issues.
  3. There exists no validation that the implementation of the package aligns with the definition.
    • For example: A function may be added in the implementation without a corresponding change in the definitions.

Could not all these concerns be resolved if package authors develop the definitions as part of their packages?

Yes and No.

It is possible to include definitions as part of a package using the @types property. This will indeed resolve the first two concerns, The problem however, is that in order to resolve the 3rd concern, that of validating the definitions match the implementation. The whole package would have had to be developed in TypeScript. Which may not be desired for various (and legitimate) reasons.

Luckily a new alternative is available since TypeScript 2.3

Suggested Pattern

The basic premise is quite simple:

  • Define our public APIs as d.ts files.

  • Use JSDocs annotations in the JS implementations of our public APIs and reference the types defined in the d.ts files.

  • Configure the TS compiler via tsconfig.json to check JS files and not generate any code output.

  • Expose our d.ts definitions using the @types property in our package.json.

Pros

  • The implementations of the public APIs must now match their definitions.
  • Our project is still a vanilla JS project.
  • Our public APIs are now easily exportable and can be easily consumed by end users
    • As opposed to using pure JSDocs.
  • We are using a better syntax than JSDocs to define our public APIs.

Cons

  • Integrating TypeScript as a "pure" type checker may require some minor modifications/fixes
    as with the integration of any linter...
  • The type checking of JS files is somewhat limited relative to that done for TS files.

Playing around with this example

First run:

npm install

Secondly run:

npm run type_check

And verify no errors are detected.

Thirdly: Modify the definitions and/or the implementation in ways that should break their alignment. and re-run

npm run type_check

To inspect the error messages.