@@ -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,93 @@ 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+ module : {
236+ loader : ( ) => { test : string } ;
237+ } ;
238+ loaderData : { test : string } ;
239+ params : unknown ;
240+ actionData : unknown ;
241+ matches : [ ] ;
242+ } > [ "loaderData" ] ,
243+ { test : string }
244+ >
245+ > ,
246+ Expect <
247+ Equal <
248+ CreateMetaArgs < {
249+ module : {
250+ loader : ( ) => { test : string } ;
251+ ErrorBoundary : Func ;
252+ } ;
253+ loaderData : { test : string } ;
254+ params : unknown ;
255+ actionData : unknown ;
256+ matches : [ ] ;
257+ } > [ "loaderData" ] ,
258+ { test : string } | undefined
259+ >
260+ > ,
261+ Expect <
262+ Equal <
263+ CreateMetaArgs < {
264+ module : { } ;
265+ loaderData : never ;
266+ params : unknown ;
267+ actionData : unknown ;
268+ matches : [ ] ;
269+ } > [ "loaderData" ] ,
270+ never
271+ >
272+ > ,
273+ Expect <
274+ Equal <
275+ CreateMetaArgs < {
276+ module : {
277+ ErrorBoundary : Func ;
278+ } ;
279+ loaderData : never ;
280+ params : unknown ;
281+ actionData : unknown ;
282+ matches : [ ] ;
283+ } > [ "loaderData" ] ,
284+ undefined
285+ >
286+ > ,
287+ // Test that MetaArgs.data (deprecated) also follows the same pattern
288+ Expect <
289+ Equal <
290+ CreateMetaArgs < {
291+ module : {
292+ loader : ( ) => { test : string } ;
293+ } ;
294+ loaderData : { test : string } ;
295+ params : unknown ;
296+ actionData : unknown ;
297+ matches : [ ] ;
298+ } > [ "data" ] ,
299+ { test : string }
300+ >
301+ > ,
302+ Expect <
303+ Equal <
304+ CreateMetaArgs < {
305+ module : {
306+ loader : ( ) => { test : string } ;
307+ ErrorBoundary : Func ;
308+ } ;
309+ loaderData : { test : string } ;
310+ params : unknown ;
311+ actionData : unknown ;
312+ matches : [ ] ;
313+ } > [ "data" ] ,
314+ { test : string } | undefined
315+ >
316+ > ,
317+ ] ;
0 commit comments