Skip to content

Commit 0d1a584

Browse files
authored
typegen: autoimport for Route types (#12213)
* typegen: autoimport for `Route` types * typegen: update docs to use `Route` namespace * typegen: update playground to use `Route` namespace * typegen: update changeset to use `Route` namespace
1 parent 27c6fe8 commit 0d1a584

File tree

9 files changed

+32
-30
lines changed

9 files changed

+32
-30
lines changed

.changeset/typesafety.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ For example:
1111

1212
```ts
1313
// app/routes/product.tsx
14-
import type * as Route from "./+types/product";
14+
import type { Route } from "./+types/product";
1515

1616
export function loader({ params }: Route.LoaderArgs) {}
1717

docs/explanation/type-safety.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const routes: RouteConfig = [
2222
You can import route-specific types like so:
2323

2424
```tsx filename=app/routes/product.tsx
25-
import type * as Route from "./+types.product";
25+
import type { Route } from "./+types.product";
2626
// types generated for this route 👆
2727

2828
export function loader({ params }: Route.LoaderArgs) {

docs/how-to/resource-routes.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ There's a subtle detail to be aware of when linking to resource routes. You need
7676
To handle `GET` requests export a loader function:
7777

7878
```tsx
79-
import type * as Route from "./+types.resource";
79+
import type { Route } from "./+types.resource";
8080

8181
export const loader = async ({
8282
request,
@@ -90,7 +90,7 @@ export const loader = async ({
9090
To handle `POST`, `PUT`, `PATCH` or `DELETE` requests export an action function:
9191

9292
```tsx
93-
import type * as Route from "./+types.resource";
93+
import type { Route } from "./+types.resource";
9494

9595
export const action = async ({
9696
request,
@@ -138,7 +138,7 @@ export const action = async () => {
138138
When calling Resource Routes using `<Form>`, `useSubmit`, or Fetchers, Client Loaders and Actions defined in the Resource Route will participate in the request lifecycle.
139139

140140
```ts
141-
import type * as Route from "./+types.github";
141+
import type { Route } from "./+types.github";
142142

143143
export const action = async () => {
144144
return Response.json(
@@ -166,7 +166,7 @@ export const clientAction = async ({
166166
Resource routes can be used to handle webhooks. For example, you can create a webhook that receives notifications from GitHub when a new commit is pushed to a repository:
167167

168168
```tsx
169-
import type * as Route from "./+types.github";
169+
import type { Route } from "./+types.github";
170170

171171
import crypto from "node:crypto";
172172

docs/start/actions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Client actions only run in the browser and take priority over a server action wh
1515

1616
```tsx filename=app/project.tsx
1717
// route('/projects/:projectId', './project.tsx')
18-
import type * as Route from "./+types.project";
18+
import type { Route } from "./+types.project";
1919
import { Form } from "react-router";
2020
import { someApi } from "./api";
2121

@@ -52,7 +52,7 @@ Server actions only run on the server and are removed from client bundles.
5252

5353
```tsx filename=app/project.tsx
5454
// route('/projects/:projectId', './project.tsx')
55-
import type * as Route from "./+types.project";
55+
import type { Route } from "./+types.project";
5656
import { Form } from "react-router";
5757
import { fakeDb } from "../db";
5858

@@ -89,7 +89,7 @@ If you need to return a custom HTTP status code or custom headers from your `act
8989

9090
```tsx filename=app/project.tsx lines=[3,11-14,19]
9191
// route('/projects/:projectId', './project.tsx')
92-
import type * as Route from "./+types.project";
92+
import type { Route } from "./+types.project";
9393
import { data } from "react-router";
9494
import { fakeDb } from "../db";
9595

docs/start/data-loading.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Data is provided to the route component from `loader` and `clientLoader`.
1313

1414
```tsx filename=app/product.tsx
1515
// route("products/:pid", "./product.tsx");
16-
import type * as Route from "./+types.product";
16+
import type { Route } from "./+types.product";
1717

1818
export async function clientLoader({
1919
params,
@@ -42,7 +42,7 @@ When server rendering, `loader` is used for both initial page loads and client n
4242

4343
```tsx filename=app/product.tsx
4444
// route("products/:pid", "./product.tsx");
45-
import type * as Route from "./+types.product";
45+
import type { Route } from "./+types.product";
4646
import { fakeDb } from "../db";
4747

4848
export async function loader({ params }: Route.LoaderArgs) {
@@ -71,7 +71,7 @@ If you need to return a custom HTTP status code or custom headers from your `loa
7171

7272
```tsx filename=app/product.tsx lines=[3,6-8,14,17-21]
7373
// route("products/:pid", "./product.tsx");
74-
import type * as Route from "./+types.product";
74+
import type { Route } from "./+types.product";
7575
import { data } from "react-router";
7676
import { fakeDb } from "../db";
7777

@@ -100,7 +100,7 @@ When pre-rendering, loaders are used to fetch data during the production build.
100100

101101
```tsx filename=app/product.tsx
102102
// route("products/:pid", "./product.tsx");
103-
import type * as Route from "./+types.product";
103+
import type { Route } from "./+types.product";
104104

105105
export async function loader({ params }: Route.LoaderArgs) {
106106
let product = await getProductFromCSVFile(params.pid);
@@ -148,7 +148,7 @@ Note that when server rendering, any URLs that aren't pre-rendered will be serve
148148

149149
```tsx filename=app/product.tsx
150150
// route("products/:pid", "./product.tsx");
151-
import type * as Route from "./+types.product";
151+
import type { Route } from "./+types.product";
152152
import { fakeDb } from "../db";
153153

154154
export async function loader({ params }: Route.LoaderArgs) {
@@ -186,7 +186,7 @@ In the future, rendered async components in loaders are available on `loaderData
186186

187187
```tsx filename=app/product-page.tsx
188188
// route("products/:pid", "./product-page.tsx");
189-
import type * as Route from "./+types.product";
189+
import type { Route } from "./+types.product";
190190
import Product from "./product";
191191
import Reviews from "./reviews";
192192

docs/start/routing.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Here's a sample route module:
7272

7373
```tsx filename=app/team.tsx
7474
// provides type safety/inference
75-
import type * as Route from "./+types.team";
75+
import type { Route } from "./+types.team";
7676

7777
// provides `loaderData` to the component
7878
export async function loader({ params }: Route.LoaderArgs) {
@@ -226,7 +226,7 @@ route("teams/:teamId", "./team.tsx"),
226226
```
227227

228228
```tsx filename=app/team.tsx
229-
import type * as Route from "./+types.team";
229+
import type { Route } from "./+types.team";
230230

231231
export async function loader({ params }: Route.LoaderArgs) {
232232
// ^? { teamId: string }
@@ -247,7 +247,7 @@ route("c/:categoryId/p/:productId", "./product.tsx"),
247247
```
248248

249249
```tsx filename=app/product.tsx
250-
import type * as Route from "./+types.product";
250+
import type { Route } from "./+types.product";
251251

252252
async function loader({ params }: LoaderArgs) {
253253
// ^? { categoryId: string; productId: string }

packages/react-router-dev/typegen.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,21 @@ function getModule(routes: RouteManifest, route: RouteManifestEntry): string {
152152
153153
export type Params = {${formattedParamsProperties(routes, route)}}
154154
155-
type Route = typeof import("./${Pathe.filename(route.file)}")
155+
type RouteModule = typeof import("./${Pathe.filename(route.file)}")
156156
157-
export type LoaderData = T.CreateLoaderData<Route>
158-
export type ActionData = T.CreateActionData<Route>
157+
export namespace Route {
158+
export type LoaderData = T.CreateLoaderData<RouteModule>
159+
export type ActionData = T.CreateActionData<RouteModule>
159160
160-
export type LoaderArgs = T.CreateServerLoaderArgs<Params>
161-
export type ClientLoaderArgs = T.CreateClientLoaderArgs<Params, Route>
162-
export type ActionArgs = T.CreateServerActionArgs<Params>
163-
export type ClientActionArgs = T.CreateClientActionArgs<Params, Route>
161+
export type LoaderArgs = T.CreateServerLoaderArgs<Params>
162+
export type ClientLoaderArgs = T.CreateClientLoaderArgs<Params, RouteModule>
163+
export type ActionArgs = T.CreateServerActionArgs<Params>
164+
export type ClientActionArgs = T.CreateClientActionArgs<Params, RouteModule>
164165
165-
export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Params>
166-
export type ComponentProps = T.CreateComponentProps<Params, LoaderData, ActionData>
167-
export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Params, LoaderData, ActionData>
166+
export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Params>
167+
export type ComponentProps = T.CreateComponentProps<Params, LoaderData, ActionData>
168+
export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Params, LoaderData, ActionData>
169+
}
168170
`;
169171
}
170172

playground/compiler/app/routes/_index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type * as Route from "./+types._index";
1+
import type { Route } from "./+types._index";
22

33
export function loader({ params }: Route.LoaderArgs) {
44
return { planet: "world", date: new Date(), fn: () => 1 };

playground/compiler/app/routes/product.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type * as Route from "./+types.product";
1+
import type { Route } from "./+types.product";
22

33
export function loader({ params }: Route.LoaderArgs) {
44
return { name: `Super cool product #${params.id}` };

0 commit comments

Comments
 (0)