Typescript: Compile ambient module declarations for publishing to NPM

869 Views Asked by At

I am looking for suggestions to automatically have TypeScript compile node (commonjs) ambient module declarations for a npm package I am currently writing in TypeScript. I seem to be running into some problems with respect to understanding the appropriate way to have TypeScript generate ambient module declarations for node / commonjs.

For some backstory, our module is currently published using scoped npm modules, so something like "@company/module". So one thing we note is that in order to have typescript be able to resolve the "scoped" module, it needs a fully qualified ambient module name "@company/module" declaration, and it is on the generation of named ambient modules, and indeed, the appropriate way to generate ambient modules declarations from the compiler that we are unsure about.

Our module is setup not too disimilar to the following example.

TypeScript

The following code is compiled as index.js and bar.js respectively.

// ./bar.ts
export class Bar {} 

// ./index.ts
import { Bar } from "./bar"

export class Foo {
   constructor(private bar: Bar) {}
}

TypeScript Declaration

The following is the idealized output we would like to generate from the typescript compiler.

// ./index.d.ts

declare module "@company/module/bar" {
  export class Bar {}
}

declare module "@company/foo" {
  import { Bar } from "@company/module/bar"
  export class Foo {
    constructor(private bar: Bar)
  }
}

There doesn't appear to be a concise / clear cut way to generate a the above declaration directly from TypeScript. However we have found a approach to work around this which is to.

  1. compile the declaration seperately using module: AMD - outFile (emits declaration bundle and "ambient" declarations)
  2. rewrite the compiled AMD declaration and prefix declare module with "@company/module" (inclusive of the import)

There seem to be a couple of github issues on the TS repository around generating bundled declarations in this fashion, but they seem to be long standing issues, these are referenced below.

Package declaration file for commonjs packages - (seems perfect) https://github.com/Microsoft/TypeScript/pull/3159

Proposal: Bundling TS module type definitions https://github.com/Microsoft/TypeScript/issues/4434

Am looking for others experiences with npm declaration publishing of TypeScript libraries to NPM. Open to all suggestions!

Many Thanks

1

There are 1 best solutions below

2
On BEST ANSWER

The following is the idealized output we would like to generate from the typescript compiler.

You don't need to do that (or at least you haven't provided a use case for it).

Your output folder e.g. /module/bar should look like:

  • index.js < generated .js for /module/bar.ts
  • index.d.ts < generated .d.ts for /module/bar.ts

And when users require @company/module/bar runtime resolves to .js and TypeScript type system resolves to .d.ts automatically.

Examples