在TypeScript+Bun中使用require引入JS库需调用.default的解决方法问询
解决方案:绕过TypeScript/Bun中动态require的.default问题
1. 手动兼容.default的封装函数
直接写个工具函数自动处理模块导出的兼容问题,不管是JS还是TS环境都能正常拿到目标实例:
function requireDefault<T>(modulePath: string): T { const module = require(modulePath); // 优先取default,没有则直接返回模块本身 return module.default ?? module; } // 使用示例 const target = requireDefault<{ execute: (task: any) => void }>(AppRoot + targetName); target.execute(targetTask);
2. 调整TS配置强化模块互转
虽然你已经开了esModuleInterop,可以再配合开启allowSyntheticDefaultImports,让TypeScript对模块导出的识别更宽松:
{ "compilerOptions": { "esModuleInterop": true, "allowSyntheticDefaultImports": true, // 其他原有配置... } }
注意这个配置主要优化静态import场景,动态require的情况还是建议结合上面的封装函数使用。
3. 改用动态import()替代require
如果项目允许异步加载,换成ES模块的动态import语法,配合TS配置能自动处理默认导出的兼容:
async function runTargetTask(targetName: string, targetTask: any) { const module = await import(AppRoot + targetName); const target = module.default ?? module; target.execute(targetTask); }
这种方式更符合现代模块规范,Bun对动态import的支持也很完善,能避免CommonJS/ES模块互转的不少坑。
4. 为JS库补全类型声明(可选)
如果这个JS库没有官方类型声明,可以自己写个简单的.d.ts文件,明确模块的默认导出类型,让TS能正确推断:
// 比如创建@types/your-lib/index.d.ts declare module "your-lib/*" { export default interface TargetModule { execute(task: any): void; } }
这样在加载模块时,TS不会再出现类型报错,也能更清晰地约束实例的方法。
内容的提问来源于stack exchange,提问作者Kaki Master Of Time
相关产品推荐
相关产品推荐

