如何在CommonJS项目中为ESM库添加自定义TypeScript类型定义?
为ESM库在CommonJS项目中扩展类型的解决方案
在CommonJS项目中给ESM库编写类型声明时,核心问题是TypeScript会默认将.d.ts文件识别为CommonJS类型,与ESM库的模块系统冲突。以下是无需迁移整个项目到ESM的解决方法:
方法1:使用.d.mts后缀的类型声明文件
这是最直接的解决方案,TypeScript会将.d.mts文件识别为对应ESM模块的类型声明,完美适配CommonJS项目中的ESM库:
- 将你的类型声明文件从
.d.ts重命名为.d.mts,例如keycloak-admin-client.d.mts - 在文件中编写扩展类型,注意不要覆盖原库类型,而是合并扩展:
declare module '@keycloak/keycloak-admin-client' { // 导入原库所有已有类型,避免覆盖 export * from '@keycloak/keycloak-admin-client'; // 添加自定义扩展的类型 export function getNum(): number; }
方法2:调整TypeScript配置(可选)
如果不想修改文件后缀,可以在tsconfig.json中调整模块解析策略,让TypeScript正确识别ESM库的类型:
- 修改
tsconfig.json中的moduleResolution为NodeNext或Node16:
{ "compilerOptions": { "moduleResolution": "NodeNext", "module": "CommonJS", // 保持项目为CommonJS模块系统 "typeRoots": ["./src/types"] // 确保你的类型声明文件目录被包含 } }
- 保持类型声明文件为
.d.ts,但在文件中使用ESM风格的导出,确保与原库的模块系统匹配。
注意事项
- 不要修改项目根目录
package.json中的type字段(保持"type": "commonjs"或不设置),避免强制项目切换到ESM。 - 扩展类型时务必先导入原库的所有类型(
export * from '库名'),否则会完全覆盖原库的类型定义,导致原库的API失去类型提示。
内容的提问来源于stack exchange,提问作者valerii15298
相关产品推荐
相关产品推荐

