Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release: typegen fixes #12443

Merged
merged 2 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .changeset/red-eagles-stare.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
20 changes: 18 additions & 2 deletions integration/typegen-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,15 +282,25 @@ 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<Equal<typeof parent1.data, { parent1: number }>>

const parent2 = matches[2]
type Test2 = Expect<Equal<typeof parent2.data, { parent2: number }>>

const current = matches[3]
type Test3 = Expect<Equal<typeof current.data, { current: number }>>

const child1 = matches[4]
type Test3 = Expect<Equal<typeof child1.data, unknown>>
type Test4a = Expect<undefined extends typeof child1 ? true : false>
if (child1) {
type Test4b = Expect<Equal<typeof child1.data, unknown>>
}
return []
}

Expand All @@ -301,8 +311,14 @@ test.describe("typegen", () => {
const parent2 = matches[2]
type Test2 = Expect<Equal<typeof parent2.data, { parent2: number }>>

const current = matches[3]
type Test3 = Expect<Equal<typeof current.data, { current: number }>>

const child1 = matches[4]
type Test3 = Expect<Equal<typeof child1.data, unknown>>
type Test4a = Expect<undefined extends typeof child1 ? true : false>
if (child1) {
type Test4b = Expect<Equal<typeof child1.data, unknown>>
}
}
`,
});
Expand Down
8 changes: 4 additions & 4 deletions packages/react-router/lib/types/route-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ type MetaMatch<T extends RouteInfo> = Pretty<
type MetaMatches<T extends RouteInfo[]> =
T extends [infer F extends RouteInfo, ...infer R extends RouteInfo[]]
? [MetaMatch<F>, ...MetaMatches<R>]
: MetaMatch<RouteInfo>[];
: Array<MetaMatch<RouteInfo> | undefined>;

export type CreateMetaArgs<T extends RouteInfo> = {
location: Location;
params: T["params"];
data: T["loaderData"];
error?: unknown;
matches: MetaMatches<T["parents"]>;
matches: MetaMatches<[...T["parents"], T]>;
};
export type MetaDescriptors = MetaDescriptor[];

Expand Down Expand Up @@ -149,13 +149,13 @@ type Match<T extends RouteInfo> = Pretty<
type Matches<T extends RouteInfo[]> =
T extends [infer F extends RouteInfo, ...infer R extends RouteInfo[]]
? [Match<F>, ...Matches<R>]
: Match<RouteInfo>[];
: Array<Match<RouteInfo> | undefined>;

export type CreateComponentProps<T extends RouteInfo> = {
params: T["params"];
loaderData: T["loaderData"];
actionData?: T["actionData"];
matches: Matches<T["parents"]>;
matches: Matches<[...T["parents"], T]>;
};

export type CreateErrorBoundaryProps<T extends RouteInfo> = {
Expand Down
Loading