Simple way to access parent params in all nested paths #542
-
I'm struggling a bit with how to handle typed params in child routes Say I have these pages
I then create a navbar component that displays just slightly differently when used inside company pages based on the companyId param. Without typed params I could just do a simple undefined check const companyId = route.params?.companyId;
if(companyId !== undefined){
// do something with id
} But with typed params I'm not allowed to do the undefined check because of the never record type. // This results in a type error and also doesn't autocomplete
const companyId = route.params?.companyId;
// This route would be incorrect for the home page
const route useRoute('/company/[companyId]')
// I had hoped this would work but it seems typescript doesn't narrow types with includes.
if(
route.name.includes('/company/[companyId]')
){
route.params.companyId // type error
}
// This works but can quickly get long and requires updates every time a new company page is added
if(
route.name === '/company/[companyId]' ||
route.name === '/company/[companyId]/employees' ||
route.name === '/company/[companyId]/financials' ||
){
route.params.companyId // works
} My only other idea would be to send in the company id to the navbar with a prop instead but that still leaves it open to forgetfulness since the component is still valid without a company id Would it be possible to extend the params to allow for name wildcards or something similar to simplify this? I'm not the best at typescript so I might just be missing something obvious, but then please enlighten me. I'm also using Nuxt if that changes anything. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
You could define a What I wouldn't do is get any sort of state from useRoute in your navbar if it's a component you use everywhere, instead let the page either pass some props or a slot to the navbar, or use a pinia store. |
Beta Was this translation helpful? Give feedback.
-
You can do import type { RouteLocationNormalizedLoaded } from 'vue-router'
function routeHasParam<
Route extends RouteLocationNormalizedLoaded,
Param extends keyof Exclude<Route['params'], Record<PropertyKey, never>>,
>(
route: Route,
key: Param
): route is Exclude<Route, { params: Record<PropertyKey, never> }> & {
params: Record<Param, unknown>
} {
return key in route.params
} |
Beta Was this translation helpful? Give feedback.
You can do
if ('companyId' in route.params)
. You can implement this in a customrouteHasParam()
function: