Skip to content

TypeScript Declarations

Bunup automatically generates TypeScript declaration files (.d.ts, .d.mts, or .d.cts) for your library based on your output format, with advanced features like declaration splitting.

Prerequisites

Enable isolatedDeclarations in your tsconfig:

tsconfig.json
json
{
  "compilerOptions": {
    "declaration": true,
    "isolatedDeclarations": true
  }
}

Bunup uses TypeScript's new isolated declarations feature to generate type declarations quickly and accurately.

Learn more about the benefits and why you need to enable this here.

Basic

Bunup automatically generates TypeScript declaration files for all TypeScript entry points that require them. Files that do not contain exports, or for which declarations are unnecessary, are skipped.

Declaration Splitting

Declaration splitting optimizes TypeScript .d.ts files when multiple entry points share types. Instead of duplicating shared types across declaration files, Bunup extracts them into shared chunk files that are imported where needed.

sh
bunup --dts.splitting
typescript
export default defineConfig({
	dts: {
		splitting: true,
	},
});

Without splitting:

dist/
├── index.d.ts           # ~45KB
└── utils.d.ts           # ~40KB

With splitting:

dist/
├── index.d.ts					# ~15KB, imports from shared chunk
├── utils.d.ts					# ~10KB, imports from shared chunk
└── shared/chunk-abc123.d.ts	# ~30KB, shared types

The result is clean declarations with no duplicates, improved readability, and reduced bundle size.

Minification

You can minify the generated declaration files to reduce their size:

sh
bunup --dts.minify
typescript
export default defineConfig({
	dts: {
		minify: true,
	},
});

Minifying TypeScript declarations is uncommon, but bunup supports it. When enabled, minification keeps public (exported) API names intact, shortens internal type names, and removes documentation comments. This can greatly reduce file size, which is useful if bundle size matters and you don't need JSDoc or readable type definitions for consumers.

Example

Original:

ts
type DeepPartial<T> = { [P in keyof T]? : DeepPartial<T[P]> };
interface Response<T> {
	data: T;
	error?: string;
	meta?: Record<string, unknown>;
}
declare function fetchData<T>(url: string, options?: RequestInit): Promise<Response<T>>;
export { fetchData, Response, DeepPartial };

Minified:

ts
type e<T>={[P in keyof T]?:e<T[P]>};interface t<T>{data:T;error?:string;meta?:Record<string,unknown>;}declare function n<T>(url:string,options?:RequestInit): Promise<t<T>>;export{n as fetchData,t as Response,e as DeepPartial};

Custom Entry Points

For more control, you can specify custom entry points for declarations:

sh
# Single entry
bunup src/index.ts src/utils.ts --dts.entry src/index.ts

# Multiple entries
bunup src/index.ts src/utils.ts src/types.ts --dts.entry src/index.ts,src/types.ts
typescript
export default defineConfig({
	entry: ['src/index.ts', 'src/utils.ts'],
	dts: {
		// Only generate declarations for index.ts
		entry: ['src/index.ts'],
	},
});

Using Glob Patterns

Bunup supports glob patterns for both main entries and declaration file entries:

sh
# Single glob pattern
bunup --dts.entry "src/public/**/*.ts"

# Multiple patterns (including exclusions)
bunup --dts.entry "src/public/**/*.ts,!src/public/dev/**/*"
typescript
export default defineConfig({
	dts: {
		entry: [
			'src/public/**/*.ts',
			'!src/public/dev/**/*'
		]
	}
});

You can use:

  • Simple patterns like src/**/*.ts to include files
  • Exclude patterns starting with ! to filter out specific files
  • Both for main entries and declaration entries

TypeScript Configuration

You can specify a custom tsconfig file to use for TypeScript declaration generation. This is mainly used for path resolution during declaration generation.

See Custom Tsconfig Path for details.

By default, the nearest tsconfig.json file will be used.

Resolving External Types

When generating declaration files, you might need to include type references from external dependencies. Bunup can automatically resolve these external types:

sh
# Enable resolving all external types
bunup --dts.resolve
ts
export default defineConfig({
      dts: {
            // Enable resolving all external types
            resolve: true,
      },
});

The resolve option helps when your TypeScript code imports types from external packages. Bunup will look for type definitions in node_modules and include them in your declaration files.

You can also specify which packages to resolve types for:

sh
# Single package
bunup --dts.resolve react

# Multiple packages
bunup --dts.resolve react,lodash,@types/node
typescript
export default defineConfig({
	dts: {
		// Only resolve types from these specific packages
		resolve: ['react', 'lodash', /^@types\//],
	},
});

Disabling Declaration Generation

While Bunup automatically generates declaration files for TypeScript entries, you can disable this feature if needed:

sh
bunup --no-dts
ts
export default defineConfig({
  entry: "src/index.ts",
  dts: false,
});

This can be useful when you want to handle declaration generation yourself or when you're working on a project that doesn't need declaration files.

Released under the MIT License.