@@ -10,7 +10,7 @@ import type {
1010 ServerDataFunctionArgs ,
1111} from "./route-data" ;
1212import type { RouteModule } from "./route-module" ;
13- import type { Pretty } from "./utils" ;
13+ import type { Pretty , Func , Expect , Equal } from "./utils" ;
1414
1515type MaybePromise < T > = T | Promise < T > ;
1616
@@ -48,6 +48,12 @@ type MetaMatches<T extends Array<MatchInfo>> =
4848 ? [ MetaMatch < F > , ...MetaMatches < R > ]
4949 : Array < MetaMatch < MatchInfo > | undefined > ;
5050
51+ type HasErrorBoundary < T extends RouteInfo > = T [ "module" ] extends {
52+ ErrorBoundary : Func ;
53+ }
54+ ? true
55+ : false ;
56+
5157type CreateMetaArgs < T extends RouteInfo > = {
5258 /** This is the current router `Location` object. This is useful for generating tags for routes at specific paths or query parameters. */
5359 location : Location ;
@@ -58,9 +64,13 @@ type CreateMetaArgs<T extends RouteInfo> = {
5864 *
5965 * @deprecated Use `Route.MetaArgs.loaderData` instead
6066 */
61- data : T [ "loaderData" ] | undefined ;
67+ data :
68+ | T [ "loaderData" ]
69+ | ( HasErrorBoundary < T > extends true ? undefined : never ) ;
6270 /** The return value for this route's server loader function */
63- loaderData : T [ "loaderData" ] | undefined ;
71+ loaderData :
72+ | T [ "loaderData" ]
73+ | ( HasErrorBoundary < T > extends true ? undefined : never ) ;
6474 /** Thrown errors that trigger error boundaries will be passed to the meta function. This is useful for generating metadata for error pages. */
6575 error ?: unknown ;
6676 /** An array of the current {@link https://api.reactrouter.com/v7/interfaces/react_router.UIMatch.html route matches}, including parent route matches. */
@@ -215,3 +225,88 @@ export type GetAnnotations<Info extends RouteInfo> = {
215225 // ErrorBoundary
216226 ErrorBoundaryProps : CreateErrorBoundaryProps < Info > ;
217227} ;
228+
229+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
230+ type __tests = [
231+ // Test that MetaArgs.loaderData is only potentially undefined when ErrorBoundary is present
232+ Expect <
233+ Equal <
234+ CreateMetaArgs < {
235+ params : unknown ;
236+ loaderData : { test : string } ;
237+ actionData : unknown ;
238+ module : { loader : ( ) => { test : string } } ;
239+ matches : [ ] ;
240+ } > [ "loaderData" ] ,
241+ { test : string }
242+ >
243+ > ,
244+ Expect <
245+ Equal <
246+ CreateMetaArgs < {
247+ params : unknown ;
248+ loaderData : { test : string } ;
249+ actionData : unknown ;
250+ module : { loader : ( ) => { test : string } ; ErrorBoundary : Func } ;
251+ matches : [ ] ;
252+ } > [ "loaderData" ] ,
253+ { test : string } | undefined
254+ >
255+ > ,
256+ Expect <
257+ Equal <
258+ CreateMetaArgs < {
259+ params : unknown ;
260+ loaderData : never ;
261+ actionData : unknown ;
262+ module : { } ;
263+ matches : [ ] ;
264+ } > [ "loaderData" ] ,
265+ never
266+ >
267+ > ,
268+ Expect <
269+ Equal <
270+ CreateMetaArgs < {
271+ params : unknown ;
272+ loaderData : never ;
273+ actionData : unknown ;
274+ module : {
275+ ErrorBoundary : Func ;
276+ } ;
277+ matches : [ ] ;
278+ } > [ "loaderData" ] ,
279+ undefined
280+ >
281+ > ,
282+ // Test that MetaArgs.data (deprecated) also follows the same pattern
283+ Expect <
284+ Equal <
285+ CreateMetaArgs < {
286+ params : unknown ;
287+ loaderData : { test : string } ;
288+ actionData : unknown ;
289+ module : {
290+ loader : ( ) => { test : string } ;
291+ } ;
292+ matches : [ ] ;
293+ } > [ "data" ] ,
294+ { test : string }
295+ >
296+ > ,
297+ Expect <
298+ Equal <
299+ CreateMetaArgs < {
300+ params : unknown ;
301+ loaderData : { test : string } ;
302+ actionData : unknown ;
303+ module : {
304+ loader : ( ) => { test : string } ;
305+ ErrorBoundary : Func ;
306+ } ;
307+ matches : [ ] ;
308+ } > [ "data" ] ,
309+ { test : string } | undefined
310+ >
311+ > ,
312+ ] ;
0 commit comments