chartjs-plugin-annotation icon indicating copy to clipboard operation
chartjs-plugin-annotation copied to clipboard

Rework TypeScript .d.ts handling

Open joshkel opened this issue 4 months ago • 7 comments

This reworks .d.ts handling to address the issues in #977 and reported by Are the Types Wrong.

Background information:

  • According to the TypeScript Handbook:

    If you’re using a bundler to emit your library... You must ensure that your declaration files get bundled as well. Recall the first rule of declaration files: every declaration file represents exactly one JavaScript file.

  • According to Are the Types Wrong,

    A golden rule of declaration files is that if they represent a module—that is, if they use import or export at the top level—they must represent exactly one JavaScript file. They especially cannot represent JavaScript files of two different module formats.

  • chartjs-plugin-annotation's CJS build uses a CJS default export (see Rollup's docs). Properly representing that in a .d.ts file requires using export = Annotation, but the export = syntax both raises challenges for exporting types alongside the default export and is incompatible with ESM. (The TypeScript Handbook has even more background information here. See also tshy's documentation, "export default is the bane of hybrid TypeScript modules" - although I believe that the situation is not quite as bad as it says.)

Pulling this together for chartjs-plugin-annotation:

  • Use rollup-plugin-dts to bundle declaration files alongside the bundled library files (as recommended by the TypeScript Handbook).
  • Invoke rollup-plugin-dts twice to create separate .d.ts files for the ESM and CJS builds (and update package.json to reference those).
  • Although a CJS file with a default export can't export additional values, it is apparently possible to export types alongside the default value, if the types are placed in a namespace with the same name as the default value.
  • I had trouble finding a solution for the export = default issue. (I couldn't get rollup-plugin-dts to create an export = style definition. Changing chartjs-plugin-annotation to not use a CJS default export may be the simplest long-term solution, but it would break backward compatibility.) ~~To solve this, I added @rollup/plugin-replace to apply the necessary namespace and export = statement via string replacement.~~ (changed - see below)

Fixes #977

joshkel avatar Jul 27 '25 03:07 joshkel