如何复用整个包的类型声明?Monorepo下遗留JS包的类型复用
复用monorepo中index.d.ts类型声明的最小改动方案
问题背景
我的monorepo结构如下:
├── packages │ ├── foo │ ├── a.js │ ├── index.js │ ├── index.d.ts │ ├── package.json ├── tsconfig.json
foo是一个JavaScript编写的遗留包,index.js导出了所有供其他包导入的对象。我为它编写了index.d.ts声明文件:
// foo/index.d.ts declare module 'foo' { // 导出所有可用对象 export const something: SomeThing; // ...其他导出内容 }
现在我要在foo包下新增b.ts文件,使用相对导入时出现类型错误:
// foo/b.ts import { something } from './a' // 错误:找不到模块的声明文件...
尽管index.d.ts中已经包含了相关类型声明,但依然报错。我尝试过两种解决方式:
- 给
a.js新增单独的a.d.ts声明文件,重复定义类型 - 使用包名导入而非相对导入:
import { something } from 'foo'
但第二种方案合理性存疑,还担心会引发循环依赖。想找一种最小改动的方式,直接复用index.d.ts中的类型声明。
可行解决方案
1. 在index.d.ts中补充相对模块声明
无需新增文件,直接在现有的index.d.ts中添加对./a相对模块的声明,复用已有的类型:
// foo/index.d.ts declare module 'foo' { export const something: SomeThing; // ...其他导出内容 } // 新增相对模块的类型声明,复用foo模块的类型 declare module './a' { export const something: import('foo').SomeThing; }
这样b.ts中的相对导入就能直接识别到类型,不用重复定义,改动仅需几行代码。
2. 配置TypeScript识别包的类型入口
首先确保foo/package.json中指定类型入口为index.d.ts:
// foo/package.json { "name": "foo", "types": "./index.d.ts", // ...其他配置项 }
接着在根目录的tsconfig.json中配置路径解析,确保TypeScript能正确识别monorepo中的包:
// tsconfig.json { "compilerOptions": { "baseUrl": ".", "paths": { "*": ["packages/*"] }, "preserveSymlinks": true } }
之后使用import { something } from 'foo'其实不会产生循环依赖——只要b.ts没有被index.js或a.js反向导入,就不会形成闭环。若有顾虑,可检查导入链路确认无循环。
3. 类型导入+断言复用类型
如果仅需在b.ts中复用类型,可直接从foo模块导入类型,再对相对导入的内容做类型断言:
// foo/b.ts import type { SomeThing } from 'foo'; import { something } from './a'; // 复用index.d.ts中的类型 const typedSomething = something as SomeThing;
此方案无需修改任何声明文件,仅在b.ts中添加少量代码,改动最小。
内容的提问来源于stack exchange,提问作者JieamI
相关产品推荐
相关产品推荐

