Skip to content

Commit c4642c8

Browse files
RSC: tighten route match typing in server render (#14830)
1 parent d827bb9 commit c4642c8

File tree

2 files changed

+33
-27
lines changed

2 files changed

+33
-27
lines changed

contributors.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301
- mtendekuyokwa19
302302
- mtliendo
303303
- namoscato
304+
- Nandann018-ux
304305
- nanianlisao
305306
- ned-park
306307
- nenene3

packages/react-router/lib/rsc/server.rsc.ts

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
} from "../router/router";
2121
import {
2222
type ActionFunction,
23-
type DataRouteMatch,
2423
type LoaderFunction,
2524
type Params,
2625
type ShouldRevalidateFunction,
@@ -212,6 +211,8 @@ export type RSCRouteConfigEntry = RSCRouteConfigEntryBase & {
212211

213212
export type RSCRouteConfig = Array<RSCRouteConfigEntry>;
214213

214+
type RSCRouteDataMatch = RouteMatch<string, RSCRouteConfigEntry>;
215+
215216
export type RSCRouteManifest = {
216217
clientAction?: ClientActionFunction;
217218
clientLoader?: ClientLoaderFunction;
@@ -1134,7 +1135,7 @@ async function getRenderPayload(
11341135
});
11351136

11361137
let matchesPromise = Promise.all(
1137-
staticContext.matches.map((match, i) => {
1138+
(staticContext.matches as RSCRouteDataMatch[]).map((match, i) => {
11381139
let isBelowErrorBoundary = i > deepestRenderedRouteIdx;
11391140
let parentId = parentIds[match.route.id];
11401141
return getRSCRouteMatch({
@@ -1171,24 +1172,24 @@ async function getRSCRouteMatch({
11711172
parentId,
11721173
}: {
11731174
staticContext: StaticHandlerContext;
1174-
match: DataRouteMatch;
1175+
match: RSCRouteDataMatch;
11751176
isBelowErrorBoundary: boolean;
11761177
routeIdsToLoad: string[] | null;
11771178
parentId: string | undefined;
11781179
}) {
1179-
// @ts-expect-error - FIXME: Fix the types here
1180-
await explodeLazyRoute(match.route);
1181-
const Layout = (match.route as any).Layout || React.Fragment;
1182-
const Component = (match.route as any).Component;
1183-
const ErrorBoundary = (match.route as any).ErrorBoundary;
1184-
const HydrateFallback = (match.route as any).HydrateFallback;
1185-
const loaderData = staticContext.loaderData[match.route.id];
1186-
const actionData = staticContext.actionData?.[match.route.id];
1180+
const route = match.route;
1181+
await explodeLazyRoute(route);
1182+
const Layout = route.Layout || React.Fragment;
1183+
const Component = route.Component;
1184+
const ErrorBoundary = route.ErrorBoundary;
1185+
const HydrateFallback = route.HydrateFallback;
1186+
const loaderData = staticContext.loaderData[route.id];
1187+
const actionData = staticContext.actionData?.[route.id];
11871188
const params = match.params;
11881189
// TODO: DRY this up once it's fully fleshed out
11891190
let element: React.ReactElement | undefined = undefined;
11901191
let shouldLoadRoute =
1191-
!routeIdsToLoad || routeIdsToLoad.includes(match.route.id);
1192+
!routeIdsToLoad || routeIdsToLoad.includes(route.id);
11921193
// Only bother rendering Server Components for routes that we're surfacing,
11931194
// so nothing at/below an error boundary and prune routes if included in
11941195
// `routeIdsToLoad`. This is specifically important when a middleware
@@ -1217,7 +1218,7 @@ async function getRSCRouteMatch({
12171218
let error: unknown = undefined;
12181219

12191220
if (ErrorBoundary && staticContext.errors) {
1220-
error = staticContext.errors[match.route.id];
1221+
error = staticContext.errors[route.id];
12211222
}
12221223
const errorElement = ErrorBoundary
12231224
? React.createElement(
@@ -1251,33 +1252,37 @@ async function getRSCRouteMatch({
12511252
)
12521253
: undefined;
12531254

1255+
const hmrRoute = route as RSCRouteConfigEntry & {
1256+
__ensureClientRouteModuleForHMR?: unknown;
1257+
};
1258+
12541259
return {
1255-
clientAction: (match.route as any).clientAction,
1256-
clientLoader: (match.route as any).clientLoader,
1260+
clientAction: route.clientAction,
1261+
clientLoader: route.clientLoader,
12571262
element,
12581263
errorElement,
1259-
handle: (match.route as any).handle,
1260-
hasAction: !!match.route.action,
1264+
handle: route.handle,
1265+
hasAction: !!route.action,
12611266
hasComponent: !!Component,
12621267
hasErrorBoundary: !!ErrorBoundary,
1263-
hasLoader: !!match.route.loader,
1268+
hasLoader: !!route.loader,
12641269
hydrateFallbackElement,
1265-
id: match.route.id,
1266-
index: match.route.index,
1267-
links: (match.route as any).links,
1268-
meta: (match.route as any).meta,
1270+
id: route.id,
1271+
index: "index" in route ? route.index : undefined,
1272+
links: route.links,
1273+
meta: route.meta,
12691274
params,
12701275
parentId,
1271-
path: match.route.path,
1276+
path: route.path,
12721277
pathname: match.pathname,
12731278
pathnameBase: match.pathnameBase,
1274-
shouldRevalidate: (match.route as any).shouldRevalidate,
1279+
shouldRevalidate: route.shouldRevalidate,
12751280
// Add an unused client-only export (if present) so HMR can support
12761281
// switching between server-first and client-only routes during development
1277-
...((match.route as any).__ensureClientRouteModuleForHMR
1282+
...(hmrRoute.__ensureClientRouteModuleForHMR
12781283
? {
1279-
__ensureClientRouteModuleForHMR: (match.route as any)
1280-
.__ensureClientRouteModuleForHMR,
1284+
__ensureClientRouteModuleForHMR:
1285+
hmrRoute.__ensureClientRouteModuleForHMR,
12811286
}
12821287
: {}),
12831288
};

0 commit comments

Comments
 (0)