如何生成包含外部类型声明合并的TypeScript类型包?
TypeScript声明合并打包后失效的解决方案
问题背景
开发包含声明合并的TypeScript类型包时遇到异常:通过声明合并扩展json-schema模块的JSONSchema7接口,本地使用完全正常,但使用rollup-plugin-dts、tsup等工具打包后,外部模块的类型被扁平化处理,导致声明合并失效。
原示例代码
import type { JSONSchema7 } from "json-schema"; declare module "json-schema" { interface JSONSchema7 { additionalProperty1: unknown; additionalProperty2?: unknown; [key: string]: any; } } export interface SchemaObject extends JSONSchema7 {}
打包后失效的代码示例
interface JSONSchema7 { originalProperty1: unknown; originalProperty2?: unknown; } declare module "json-schema" { interface JSONSchema7 { additionalProperty1: unknown; additionalProperty2?: unknown; [key: string]: any; } } export interface SchemaObject extends JSONSchema7 {}
全量导入尝试的代码
import type * as JSONSchema from "json-schema"; declare module "json-schema" { interface JSONSchema7 { additionalProperty1: unknown; additionalProperty2?: unknown; [key: string]: any; } } export interface SchemaObject extends JSONSchema.JSONSchema7 {}
解决方案
方法1:配置打包工具跳过外部类型处理
打包工具的默认逻辑会将外部依赖的类型内联到输出文件,破坏声明合并结构。需要显式标记外部依赖,不让工具处理其类型:
- tsup配置:在
tsup.config.ts中添加external字段指定外部依赖
import { defineConfig } from "tsup"; export default defineConfig({ dts: true, external: ["json-schema"], // 标记该模块为外部依赖,不打包其类型 });
- rollup-plugin-dts配置:在Rollup配置中用
external排除目标模块
import dts from "rollup-plugin-dts"; import resolve from "@rollup/plugin-node-resolve"; export default { input: "src/index.ts", output: { file: "dist/index.d.ts", format: "es" }, external: ["json-schema"], // 排除外部依赖类型的打包 plugins: [resolve(), dts()], };
方法2:拆分声明合并到独立文件
将声明合并的代码单独放在一个.d.ts文件中,确保打包工具保留其模块声明结构,不进行扁平化:
// src/extensions/json-schema.d.ts declare module "json-schema" { interface JSONSchema7 { additionalProperty1: unknown; additionalProperty2?: unknown; [key: string]: any; } }
在主入口文件中导入该扩展文件:
// src/index.ts import "./extensions/json-schema.d.ts"; import type { JSONSchema7 } from "json-schema"; export interface SchemaObject extends JSONSchema7 {}
方法3:开启TypeScript的preserveSymlinks配置
在tsconfig.json中启用该选项,避免模块解析路径异常导致声明合并作用域失效:
{ "compilerOptions": { "preserveSymlinks": true, // 其他编译配置... } }
内容的提问来源于stack exchange,提问作者moontai0724
相关产品推荐
相关产品推荐

