DEV Community

loading...

Rollup dts file using TSUP

egoist profile image EGOIST ・2 min read

I just improved dts generation in TSUP, a library to help you bundle TypeScript libraries real fast, previously you can use --dts flag to rollup .d.ts files, but third-party types are not resolved, for example, I often import some type utilities from the ts-essentials library:

// index.ts
import type { MarkRequired } from 'ts-essentials'

export type Options = { foo?: string }

export type NewOptions = MarkRequired<Options, 'foo'>

export const myLib = (options: Options): NewOptions => {
  return { ...options, foo: options.foo || 'default value' }
}
Enter fullscreen mode Exit fullscreen mode

If you run tsup index.ts --dts, the output dist/index.d.ts will look like:

import { MarkRequired } from 'ts-essentials';

declare type Options = {
    foo?: string;
};
declare type NewOptions = MarkRequired<Options, 'foo'>;
declare const myLib: (options: Options) => NewOptions;

export { NewOptions, Options, myLib };
Enter fullscreen mode Exit fullscreen mode

The library ts-essentials only provide types, so if you add it as one of the dependencies in package.json every user would have to install the whole package, even if only a single type is imported, and some people don't even use TypeScript.

Resolve external types

tsup provides a solution, which allows you to resolve and rollup external types so everything1 results in a single .d.ts file, run tsup index.ts --dts-resolve and the new dist/index.d.ts would be:

/** Mark some properties as required, leaving others unchanged */
declare type MarkRequired<T, RK extends keyof T> = Exclude<T, RK> & Required<Pick<T, RK>>;

declare type Options = {
    foo?: string;
};
declare type NewOptions = MarkRequired<Options, 'foo'>;
declare const myLib: (options: Options) => NewOptions;

export { NewOptions, Options, myLib };
Enter fullscreen mode Exit fullscreen mode

No additional package now! 🥳


Know more about TSUP:


  1. --dts-resolve will ignore packages specified in the dependencies field in package.json, meaning they're always externalized. 

Discussion (0)

pic
Editor guide