From 748e9eb5e4eb21d1f8afda888f991c5454e9dde7 Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Mon, 2 Dec 2024 18:24:11 -0500 Subject: [PATCH 1/2] typegen current route info into `matches` --- .changeset/red-eagles-stare.md | 4 ++-- integration/typegen-test.ts | 14 ++++++++++++-- packages/react-router/lib/types/route-module.ts | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.changeset/red-eagles-stare.md b/.changeset/red-eagles-stare.md index 6278690be5..bc94d10f28 100644 --- a/.changeset/red-eagles-stare.md +++ b/.changeset/red-eagles-stare.md @@ -3,8 +3,8 @@ "react-router": patch --- -Generate wide `matches` and `params` types for child routes +Generate wide `matches` and `params` types for current route and child routes At runtime, `matches` includes child route matches and `params` include child route path parameters. -But previously, we only generated types for parent routes and the current route in `matches` and `params`. +But previously, we only generated types for parent routes in `matches`; for `params`, we only considered the parent routes and the current route. To align our generated types more closely to the runtime behavior, we now generate more permissive, wider types when accessing child route information. diff --git a/integration/typegen-test.ts b/integration/typegen-test.ts index e2838e3480..d828a5e8be 100644 --- a/integration/typegen-test.ts +++ b/integration/typegen-test.ts @@ -282,6 +282,10 @@ test.describe("typegen", () => { import { Expect, Equal } from "../expect-type" import type { Route } from "./+types/current" + export function loader() { + return { current: 3 } + } + export function meta({ matches }: Route.MetaArgs) { const parent1 = matches[1] type Test1 = Expect> @@ -289,8 +293,11 @@ test.describe("typegen", () => { const parent2 = matches[2] type Test2 = Expect> + const current = matches[3] + type Test3 = Expect> + const child1 = matches[4] - type Test3 = Expect> + type Test4 = Expect> return [] } @@ -301,8 +308,11 @@ test.describe("typegen", () => { const parent2 = matches[2] type Test2 = Expect> + const current = matches[3] + type Test3 = Expect> + const child1 = matches[4] - type Test3 = Expect> + type Test4 = Expect> } `, }); diff --git a/packages/react-router/lib/types/route-module.ts b/packages/react-router/lib/types/route-module.ts index d4c3333195..c07001ebc0 100644 --- a/packages/react-router/lib/types/route-module.ts +++ b/packages/react-router/lib/types/route-module.ts @@ -55,7 +55,7 @@ export type CreateMetaArgs = { params: T["params"]; data: T["loaderData"]; error?: unknown; - matches: MetaMatches; + matches: MetaMatches<[...T["parents"], T]>; }; export type MetaDescriptors = MetaDescriptor[]; @@ -155,7 +155,7 @@ export type CreateComponentProps = { params: T["params"]; loaderData: T["loaderData"]; actionData?: T["actionData"]; - matches: Matches; + matches: Matches<[...T["parents"], T]>; }; export type CreateErrorBoundaryProps = { From 463174f7c2f82bdcd16b6f9643009041f0360b2d Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Mon, 2 Dec 2024 18:33:29 -0500 Subject: [PATCH 2/2] child matches may be undefined --- integration/typegen-test.ts | 10 ++++++++-- packages/react-router/lib/types/route-module.ts | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/integration/typegen-test.ts b/integration/typegen-test.ts index d828a5e8be..409ac8c14b 100644 --- a/integration/typegen-test.ts +++ b/integration/typegen-test.ts @@ -297,7 +297,10 @@ test.describe("typegen", () => { type Test3 = Expect> const child1 = matches[4] - type Test4 = Expect> + type Test4a = Expect + if (child1) { + type Test4b = Expect> + } return [] } @@ -312,7 +315,10 @@ test.describe("typegen", () => { type Test3 = Expect> const child1 = matches[4] - type Test4 = Expect> + type Test4a = Expect + if (child1) { + type Test4b = Expect> + } } `, }); diff --git a/packages/react-router/lib/types/route-module.ts b/packages/react-router/lib/types/route-module.ts index c07001ebc0..39e59e422c 100644 --- a/packages/react-router/lib/types/route-module.ts +++ b/packages/react-router/lib/types/route-module.ts @@ -48,7 +48,7 @@ type MetaMatch = Pretty< type MetaMatches = T extends [infer F extends RouteInfo, ...infer R extends RouteInfo[]] ? [MetaMatch, ...MetaMatches] - : MetaMatch[]; + : Array | undefined>; export type CreateMetaArgs = { location: Location; @@ -149,7 +149,7 @@ type Match = Pretty< type Matches = T extends [infer F extends RouteInfo, ...infer R extends RouteInfo[]] ? [Match, ...Matches] - : Match[]; + : Array | undefined>; export type CreateComponentProps = { params: T["params"];