Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why publish the TypeScript declaration file on DefinitelyTyped for a Javascript library?

I published two Javascript libraries on npm and users have asked for TypeScript type definitions for both of them. I don't use TypeScript myself and I have no plans to rewrite those libraries in TypeScript, but I'd still like to add the type definition files if only for better IntelliSense code completion. I'm looking for some advice with this.

I started with reading the docs of the DefinitelyTyped project and the documentation on publishing a declaration file for an npm package. Both sources state that "publishing to the @types organization on npm" is the preferred approach for projects not written in TypeScript.

Why is that preferred over publishing type definitions alongside the library itself via the types field in package.json? I really don't see the point in involving a third party in this. It seems like updating the type definitions and versioning them is just more complicated this way.

Quotes from the documentation referenced above (emphasis mine)

From DefinitelyTyped:

If you are the library author and your package is written in TypeScript, bundle the autogenerated declaration files in your package instead of publishing to Definitely Typed.

From typescriptlang.org:

Now that you have authored a declaration file following the steps of this guide, it is time to publish it to npm. There are two main ways you can publish your declaration files to npm:

  • bundling with your npm package, or
  • publishing to the @types organization on npm.

If your package is written in TypeScript then the first approach is favored. Use the --declaration flag to generate declaration files. This way, your declarations and JavaScript will always be in sync.

If your package is not written in TypeScript then the second is the preferred approach.

Both seem to say:

if (isAuthor && lang === "typescript")
  bundle();
else
  publishOnDefinitelyTyped();
like image 618
bernie Avatar asked Jul 01 '19 10:07

bernie


People also ask

What is the purpose of a TypeScript declaration file?

Declaration files, if you're not familiar, are just files that describe the shape of an existing JavaScript codebase to TypeScript. By using declaration files (also called . d. ts files), you can avoid misusing libraries and get things like completions in your editor.

Is it possible to generate TypeScript declaration files from JS library?

With TypeScript 3.7, TypeScript added support for generating . d. ts files from JavaScript using JSDoc syntax. This set up means you can own the editor experience of TypeScript-powered editors without porting your project to TypeScript, or having to maintain .

What Is A TypeScript declaration?

TypeScript includes declaration files for all of the standardized built-in APIs available in JavaScript runtimes. This includes things like methods and properties of built-in types like string or function , top-level names like Math and Object , and their associated types.


1 Answers

Type declaration publishing guides seem a bit outdated and sparse in several areas.

I'll try to compare both scenarios in detail.

1. Types bundled together with the npm package

1.1. From package consumer perspective

1.1.1. Pros

In general, package bundled types are more convenient thanks to streamlined dependency management.

  • no need for additional @types dependency (adding package dependency)
  • no need to synchronize versions between the package and it's types (upgrading package dependency)

1.1.2. Cons

  • limited ways to opt-out from using package bundled types

    Involves cases when the consumer needs to modify or substitute type declarations.

    The process can be considerably problematic in projects with opinionated build setups, due to the already limited configuration options.

1.2. From package author perspective

1.2.1. Pros

  • library owner can release patches and updates of type declarations at his will, at any frequency or schedule
  • no restrictions on third party or external type dependencies
  • providing concurrent support for multiple versions is carried out in the same manner as for the actual code

1.2.2. Cons

Having types bundled with package means that there are in fact two API contracts published each time a version is released.

Example:

Let's assume a library which aims to conform to semver versioning.

  • latest release -> 1.0.0
  • major version is bumped due to a breaking change -> 2.0.0
  • a critical bug in type declarations is reported, the release is broken for a group of users with typescript projects
  • a fix in types is a breaking change

The options for next version are:

A. 2.X.X -> violates semver rules for type declarations

B. 3.0.0 -> violates semver rules for the actual code

It's likely that there are numerous variations of such scenario.

2. Publishing to Definitely typed repository

2.1. From package consumer perspective

2.1.1. Pros

  • simple opt-out via removal of @types dependency

2.1.2. Cons

  • package consumer is responsibile for keeping the package and related types versions in sync

2.2. From package author perspective

2.2.1. Pros

  • types have no impact on the package's release cycle

  • DT repo comes with two extra traits:

    • dts-lint library for type assertions and type testing
    • an in-deep performance and compiler footprint analysis, including a diff between the latest package version and the package after PR modifications.

    First tool can be incorporated into another package repo with minor effort. I'm not sure if the analysis can be replicated in one's own repository, but it contains a lot of valuable data.

2.2.2. Cons

  • non-standard way of supporting past releases

  • type release schedule constrained by DT review and release cycles

    Assuming that the DefinitelyTyped PR creator is the @types package owner, it usually takes between one to two days before the PR is merged. Additionally, there's a minor delay before types-publisher updates PR related @types npm package.

    Additional review process is involved in cases when the PR is author's first contribution to a given package.

  • using external dependencies

    TypeScript handbook says:

    If your type definitions depend on another package:

    Don’t combine it with yours, keep each in their own file.

    Don’t copy the declarations in your package either.

    Do depend on the npm type declaration package if it doesn’t package its declaration files.

    Judging by the amount of redundant utility types, these are hardly respected.

    The author of type declarations is allowed to use adjacent DT repository types. Depending on packages from beyond this list requires them to be on types-publisher whitelist.

    New packages can be whitelisted by submitting a PR to types-publisher. It took over two weeks for my PR to be merged. I don't know if that's usual since I had submitted a single PR.

  • DT repo volume

    I have no cross-IDE comparison or experience, but as far as JetBrains IDEs are concerned, the memory footprint of fully indexed DT repo project made the IDE unusable.

    Disabling recompilation on changes helps to some extent. The frustrating IDE experience can be worked around by removing DT repo contents that are not relevant to the package of interest.

like image 64
Tomasz Zabłocki Avatar answered Oct 29 '22 14:10

Tomasz Zabłocki