自动类型生成规则
React Router v7 有一个自动类型生成系统,它会:
- 扫描
routes/
目录中的所有路由文件 - 为每个路由文件自动生成对应的类型文件
- 类型文件名必须与路由文件名完全匹配

🎯 为什么必须同名?
1. 自动映射机制
React Router v7 使用约定优于配置的原则:
bash
路由文件:app/routes/loader-error.tsx
类型文件:.react-router/types/app/routes/+types/loader-error.ts
文件名映射规则:
loader-error.tsx
→loader-error.ts
error-test.tsx
→error-test.ts
home.tsx
→home.ts
2. TypeScript 路径解析
当你写 import type { Route } from "./+types/loader-error"
时:
- TypeScript 查找
./+types/loader-error.ts
- 实际解析到
.react-router/types/app/routes/+types/loader-error.ts
- 这个文件包含了
loader-error.tsx
的所有类型定义
3. 类型安全保证
查看 tsconfig.json 路径映射:
关键配置:
"rootDirs": [".", "./.react-router/types"]
- 告诉 TypeScript 将两个目录视为同一个根目录".react-router/types/**/*"
- 包含生成的类型文件
💡 实际工作流程
开发时的类型生成流程:
- 你创建
app/routes/my-page.tsx
- 运行
npm run typecheck
或npm run dev
- React Router 自动生成
.react-router/types/app/routes/+types/my-page.ts
- 你可以导入
import type { Route } from "./+types/my-page"
为什么不能随意命名?
如果你写成:
typescript
import type { Route } from "./+types/some-other-name" // ❌ 错误
TypeScript 会报错,因为:
- 没有
some-other-name.ts
文件 - React Router 只会生成与路由文件同名的类型文件
🔧 验证这个机制
让我创建一个新的路由文件来演示:
jsx
// routes/demo.tsx
import type { Route } from "./+types/demo";
export function meta({}: Route.MetaArgs) {
return [
{ title: "演示页面" },
];
}
export default function Demo() {
return (
<div>
<h1>这是演示页面</h1>
<p>文件名:demo.tsx</p>
<p>类型文件:+types/demo.ts</p>
</div>
);
}
现在运行类型生成来创建对应的类型文件:
bash
npm run typecheck
我需要先将新路由添加到路由配置中:
typescript
//routes.ts
import { type RouteConfig, index, route } from "@react-router/dev/routes";
export default [
index("routes/home.tsx"),
route("error-test", "routes/error-test.tsx"),
route("loader-error", "routes/loader-error.tsx"),
route("demo", "routes/demo.tsx"),
] satisfies RouteConfig;
现在再次运行类型生成:
bash
npm run typecheck
完美!现在类型文件已经生成。
📋 总结
1. 自动化约定
bash
路由文件:app/routes/demo.tsx
配置文件:app/routes.ts (添加路由)
生成文件:.react-router/types/app/routes/+types/demo.ts
导入路径:./+types/demo
2. 一一对应关系
- 每个路由文件 → 一个对应的类型文件
- 文件名必须完全匹配(除了扩展名)
- 这确保了类型安全和自动补全
3. 开发工作流
- 创建
my-route.tsx
- 在
routes.ts
中配置路由 - 运行
npm run typecheck
- 自动生成
+types/my-route.ts
- 导入
import type { Route } from "./+types/my-route"
4. 为什么不能随意命名?
- 类型生成是自动的,基于文件名
- TypeScript 需要找到对应的类型文件
- 保证类型定义与实际路由文件匹配
这种设计确保了类型安全 、自动化 和一致性!