Bundling of .d.ts declarations of external modules

1.4k Views Asked by At

My intention is to bundle TypeScript definitions of TS code written by myself with definitions of external modules residing in node_modules. The reasoning behind is that I need to supply these joint definitions to a web-based TS code editor (MonacoEditor) to allow for code completion.

So far I have gotten some things to work with rollup-plugin-ts and have also asked the question below in the rollup-plugin-ts github issue #164, so far without any answer. I have also experimented with rollup-plugin-dts, but couldn't get it to work any better. I am however open to the choice of framework (doesn't need to be rollup), I just need definitions of custom code, node-internal modules and external modules to be bundled into a single .d.ts file that only exports what the entry point .ts file exported.

What I have working quite well:

  • Transpiling .ts to .js and bundling into a single .js file (note: I don't need the .js file; in the end I would turn on emitDeclarationOnly, but this isn't too relevant now). This is working for custom code, node-internal modules (such as 'path') and external modules (such as 'typeorm')
  • Transpiling .ts to .d.ts only for custom code

What isn't working yet:

  • Transpiling .ts to .d.ts for node-internal and external modules only references the modules but I would like to have them inlined in the same .d.ts file

Now is there any way how I can force rollup-plugin-ts (or use any other tool) to inline external type definitions as well?

For reference, I have created the following minimal repo, including the output .js and .d.ts: https://github.com/sumbricht/rollup_dts_example. In reality it would include definitions for around 100 external modules, therefore manually managing wouldn't be feasible; alternative automatable approaches are however also welcome :-).

Below the main files: rollup.config.js:

import ts from 'rollup-plugin-ts'
import commonjs from '@rollup/plugin-commonjs'
import nodeResolve from '@rollup/plugin-node-resolve'
import polyfill from 'rollup-plugin-polyfill-node'

const config = [
    {
        input: "./src/entrypoint.ts",
        output: [{ file: "./dist/entrypoint.js", format: "es" }],
        plugins: [
            polyfill(),
            commonjs(),
            nodeResolve(),
            ts({
                tsconfig: './tsconfig.json',
                exclude: [],
            })
        ],
    },
];

export default config;

tsconfig.json:

{
  "compilerOptions": {
    /* Language and Environment */
    "target": "ESNext",

    /* Modules */
    "module": "ESNext",
    "moduleResolution": "node",
    "typeRoots": ["node_modules/@types"],
    "types": ["node"],

    /* Emit */
    "declaration": true,
  },
  "exclude": []
}

entrypoint.ts:

// code by myself: nicely reflected in .js and .d.ts
export { Foo } from './foo'

// node-internal code: nicely reflected in .js but as external reference in .d.ts
export { dirname } from 'path'

// external module: nicely reflected in .js but as external reference in .d.ts
export { createConnection } from 'typeorm'

entrypoint.js:

class Foo {
    foo;
    constructor(foo) {
        this.foo = foo;
    }
    printFoo() {
        console.log(this.foo);
    }
}

// code from 'path' and 'typeorm' (cut for brevity)

export { Foo, createConnection$1 as createConnection, dirname };

entrypoint.d.ts:

declare class Foo {
    private foo;
    constructor(foo: string);
    printFoo(): void;
}
export { Foo };
export { dirname } from 'path';
export { createConnection } from 'typeorm';
1

There are 1 best solutions below

0
user22750604 On

I have a pretty similar use case. You might want to check out the tsup with --dts-resolve option. It allows you to resolve and bundle external types into a single .d.ts file. You can add the --dts-only option if you want .d.ts file only.

The official docs doesn't have much of information about it, but this blog can give you an idea.