File tree Expand file tree Collapse file tree 2 files changed +69
-13
lines changed 
packages/react-router-dev/typegen Expand file tree Collapse file tree 2 files changed +69
-13
lines changed Original file line number Diff line number Diff line change 1+ --- 
2+ " @react-router/dev "  : minor 
3+ --- 
4+ 
5+ Automatic types for future flags
6+ 
7+ Some future flags alter the way types should work in React Router.
8+ Previously, you had to remember to manually opt-in to the new types.
9+ 
10+ For example, for ` unstable_middleware ` :
11+ 
12+ ``` ts 
13+ //  react-router.config.ts
14+ 
15+ //  Step 1: Enable middleware
16+ export  default  {
17+   future: {
18+     unstable_middleware: true ,
19+   },
20+ };
21+ 
22+ //  Step 2: Enable middleware types
23+ declare  module  " react-router"   {
24+   interface  Future  {
25+     unstable_middleware:  true ; //  👈 Enable middleware types
26+   }
27+ }
28+ ``` 
29+ 
30+ It was up to you to keep the runtime future flags synced with the types for those future flags.
31+ This was confusing and error-prone.
32+ 
33+ Now, React Router will automatically enable types for future flags.
34+ That means you only need to specify the runtime future flag:
35+ 
36+ ``` ts 
37+ //  react-router.config.ts
38+ 
39+ //  Step 1: Enable middleware
40+ export  default  {
41+   future: {
42+     unstable_middleware: true ,
43+   },
44+ };
45+ 
46+ //  No step 2! That's it!
47+ ``` 
48+ 
49+ Behind the scenes, React Router will generate the corresponding ` declare module `  into ` .react-router/types ` .
50+ Currently this is done in ` .react-router/types/+register.ts `  but this is an implementation detail that may change in the future.
Original file line number Diff line number Diff line change @@ -31,21 +31,23 @@ export async function watch(
3131  await  writeAll ( ctx ) ; 
3232  logger ?. info ( pc . green ( "generated types" ) ,  {  timestamp : true ,  clear : true  } ) ; 
3333
34-   ctx . configLoader . onChange ( async  ( {  result,  routeConfigChanged } )  =>  { 
35-     if  ( ! result . ok )  { 
36-       logger ?. error ( pc . red ( result . error ) ,  {  timestamp : true ,  clear : true  } ) ; 
37-       return ; 
38-     } 
34+   ctx . configLoader . onChange ( 
35+     async  ( {  result,  configChanged,  routeConfigChanged } )  =>  { 
36+       if  ( ! result . ok )  { 
37+         logger ?. error ( pc . red ( result . error ) ,  {  timestamp : true ,  clear : true  } ) ; 
38+         return ; 
39+       } 
3940
40-     ctx . config  =  result . value ; 
41-     if  ( routeConfigChanged )  { 
42-       await  writeAll ( ctx ) ; 
43-       logger ?. info ( pc . green ( "regenerated types" ) ,  { 
44-         timestamp : true , 
45-         clear : true , 
46-       } ) ; 
41+       ctx . config  =  result . value ; 
42+       if  ( configChanged  ||  routeConfigChanged )  { 
43+         await  writeAll ( ctx ) ; 
44+         logger ?. info ( pc . green ( "regenerated types" ) ,  { 
45+           timestamp : true , 
46+           clear : true , 
47+         } ) ; 
48+       } 
4749    } 
48-   } ) ; 
50+   ) ; 
4951
5052  return  { 
5153    close : async  ( )  =>  await  ctx . configLoader . close ( ) , 
@@ -103,6 +105,10 @@ function register(ctx: Context) {
103105      interface Register { 
104106        params: Params; 
105107      } 
108+ 
109+       interface Future { 
110+         unstable_middleware: ${ ctx . config . future . unstable_middleware }  
111+       } 
106112    } 
107113  ` ; 
108114
    
 
   
 
     
   
   
          
     
  
    
     
 
    
      
     
 
     
    You can’t perform that action at this time.
  
 
    
  
     
    
      
        
     
 
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments