Imagine you have the following object:
const ROUTES = {
PAGE_NO_PARAMS: '/hello/page/two',
PAGE_R: '/about/:id',
PAGE_Z: '/page/page/:param/:id',
PAGE_N: '/who/:x/:y/:z/page',
} as const
Can we create a set of types/interfaces for each route
so that developers are limited to using only valid parameters for the selected route?
In other words, can we generate a type from ROUTES
that behaves in a similar way to the type RouteAndParams
shown below?
interface PageNoParams = {
route: '/hello/page/two' // no params
}
interface Param1 = {
route: '/about/:id',
params: { id: string } // required params
}
interface PAGE_Z = {
route: '/page/page/:param/:id',
params: { id: string; param: string } // required params
}
interface Param3 = {
route: '/who/:x/:y/:z/page',
params: { x: string; y: string; z: string } // required params
}
type RouteAndParams = PageNoParams | Param1 | PAGE_Z | Param3;
// Examples of expected results / errors when using the generated type
// Should NOT error
const routeWithParams: RouteAndParams = {
route: '/page/page/:param/:id',
params: { 'param': 'blah', 'id': 'xxx' }
}
// Should error due to unexpected param 'x'
const routeWithParams: RouteAndParams = {
route: '/about/:id',
params: { 'id': 'xxx', 'x': 'xxx' }
}
// Should error as param 'y' is missing
const routeWithParams: RouteAndParams = {
route: '/who/:x/:y/:z/page',
params: { 'x': 'blah', 'z': 'blah' }
}
This approach aims to catch potential errors during build time instead of runtime.