Rush Monorepo中跨包导入TypeScript类型被解析为any的问题
解决Rush Monorepo中Package-B无法正确识别Package-A类型定义的问题
问题场景
在Rush管理的monorepo中,Package-B导入Package-A导出的TypeScript类型时,类型被解析为any,编辑器无类型提示,也不会触发类型校验。
现有配置
Package-A
代码文件:
// Package-A/src/index.ts export * from './types';
// Package-A/src/types.ts import type { Props as PackageAComponentPropsForExport } from '~/components/PackageAComponent'; export type PackageAComponentProps = PackageAComponentPropsForExport;
// Package-A/src/components/PackageAComponent.ts export type Props = { name: string; age: number; };
tsconfig.json:
{ "include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx", "./types/**/*.ts", "./types/**/*.d.ts", "./*.js", "./.*.js", "./*.json", "./.*.json" ], "exclude": [ "node_modules", "cjs", "lib" ], "compilerOptions": { "jsx": "react", "typeRoots": [ "./node_modules/@types", "./types" ], "allowSyntheticDefaultImports": true, "preserveSymlinks": true, "baseUrl": ".", "esModuleInterop": true, "lib": [ "dom", "es2020" ], "moduleResolution": "node", "noEmit": true, "noErrorTruncation": true, "noImplicitAny": true, "paths": { "~/*": [ "src/*" ] }, "plugins": [{ "transform": "@zerollup/ts-transform-paths" }], "resolveJsonModule": true, "skipLibCheck": true, "strict": true, "types": [ "node", "jest" ] } }
Package-B
// Package-B/src/app/index.tsx import type { PackageAComponentProps } from 'Package-A'; // 预期因缺少属性报错,但实际类型被解析为any const test: PackageAComponentProps = {};
问题原因
- Package-A的tsconfig设置了
noEmit: true,不会生成类型声明文件(.d.ts),Package-B无法读取完整的类型元信息 - Package-A的
package.json未配置types字段,无法明确告知TypeScript类型入口位置 - Rush的包链接机制无法识别未生成类型声明的包的类型信息
解决方案
步骤1:修改Package-A的tsconfig,启用类型声明生成
将noEmit改为false,添加类型声明相关配置:
{ "include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx" ], "exclude": [ "node_modules", "cjs", "lib", "types" ], "compilerOptions": { "jsx": "react", "typeRoots": [ "./node_modules/@types", "./types" ], "allowSyntheticDefaultImports": true, "preserveSymlinks": true, "baseUrl": ".", "esModuleInterop": true, "lib": [ "dom", "es2020" ], "moduleResolution": "node", "noEmit": false, "declaration": true, // 启用类型声明生成 "declarationDir": "./types", // 指定类型文件输出目录 "noErrorTruncation": true, "noImplicitAny": true, "paths": { "~/*": [ "src/*" ] }, "plugins": [{ "transform": "@zerollup/ts-transform-paths" }], "resolveJsonModule": true, "skipLibCheck": true, "strict": true, "types": [ "node", "jest" ] } }
步骤2:配置Package-A的package.json
添加类型入口声明和构建命令:
{ "types": "./types/index.d.ts", "scripts": { "build": "tsc" } }
步骤3:构建Package-A
在Package-A目录执行构建命令,或用Rush批量构建:
# 单个包构建 npm run build # Rush批量构建指定包 rush build -t Package-A
步骤4:重新链接包并验证
执行Rush链接命令,确保Package-B能正确获取Package-A的类型文件:
rush link
此时回到Package-B的代码,PackageAComponentProps会正确识别为{name: string; age: number},赋值空对象会触发类型错误提示。
内容的提问来源于stack exchange,提问作者tdc
相关产品推荐
相关产品推荐

