T
TanStack2y ago
exotic-emerald

Is there a way to not inherit the search parameters from the parent route?

I'm having some trouble in finding a strict type safe solution to my search parameters in child routes. (I am using code based routes) The case: I have a parent route with some search parameters: • param1: number • param2: number • param3?: number In my parent route I do some checks in which I want to redirect to either an external route outside of my app or redirect to one of my child routes. The problem is that the optional parameter "param3" is only needed for redirecting to the external routes. My validateSearch will accept all of these parameters however The problem: I don't need the optional "param3" in my child components as it has no use. So I added a validateSearch to my child route that only accepts: • param1: number • param2: number Now when I want to use the hook useSearch from my childRouter it adds "param3?: number" to the typing, even though my validateSearch doesn't allow that parameter. Is there a way to have only the child route parameters without the parent parameters included? I know you can do: childRoute.useSearch<typeof ChildSearchParameters>() but I would like typescript to know this out of the box without the need to use dynamic typing every time I use the useSearch hook. Reproducible stackblitz: Look for TODO in ChildComponent.tsx https://stackblitz.com/edit/github-cqxxd6-3pfhf8?file=src%2FChildComponent.tsx
Kevin Leemans
StackBlitz
Is there a way to not inherit the search parameters from the parent...
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz
14 Replies
deep-jade
deep-jade2y ago
having similar issue
rare-sapphire
rare-sapphire2y ago
param3 will still be available even if you do not include in the child search param validation, so the typing is correct.
exotic-emerald
exotic-emeraldOP2y ago
yes, I understand, however I would like to not have that param3 in the typing.
rare-sapphire
rare-sapphire2y ago
but what problem is there really, aside from aesthetics ?
deep-jade
deep-jade2y ago
It's not that rare that you start your route with 3 queryparameters and you navigate to a child that only uses 2 parameters. In that case you'd expect to only have typing of the 2 parameters if you define that in the route, no? Or do you have an other suggestion how to structure the routing to have better type guarding? One of the biggest benefits of the tanstack-router is that you have type safety but in this case you only have type safety on the highest level for your queryparameters?
exotic-emerald
exotic-emeraldOP2y ago
Yeah, like Previok mentioned, that's what i'm trying to achieve 🙂
rare-sapphire
rare-sapphire2y ago
I can only repeat this. the query param exists in the parent route, so it is accessible in the child route. if you want to hide it, you need to apply some type transformation yourself. maybe this particular route should not be a child if it shall not inherit search/path params I don't understand this point, why would you not have full type safety currently? what do you mean by "navigating to the child route"? in your example you simply render it inside the parent through an outlet maybe there is something missing in your example
deep-jade
deep-jade2y ago
so maybe the solution here would be to transform the search into defined parameters as a route? In that case you always know exactly what variable is there and which is not. I guess the desired outcome here is to have changing search parameters and have typing adjusting to that changing searchparameters. While currently if I understand it correctly the typing through the children is comming from the highest level where the search was set first? Doesn't matter if the search contains less items down the tree, it still will detect the initial search typing?
rare-sapphire
rare-sapphire2y ago
children routes inherit search params from parent routes so if a parent route defines a certain search param, it will be merged with the child's search params (if any) i still don't understand why having an additional search param available, that you won't use in some children routes, is a problem
deep-jade
deep-jade2y ago
Oke then your comments are starting to make sense to me. The example given here was trying to modify the search in it's children which isn't possible then. I tried similar things in the past
rare-sapphire
rare-sapphire2y ago
Search Params | TanStack Router Docs
Similar to how TanStack Query made handling server-state in your React applications a breeze, TanStack Router aims to unlock the power of URL search params in your applications. Why not just use URLSearchParams?
rare-sapphire
rare-sapphire2y ago
if you think the docs can be improved, feel free to submit a PR
deep-jade
deep-jade2y ago
It's not a problem. It would've been insanely nice if it was possible to narrow down the search in cases where you'd want it based on the return of the validateSearch Docs are great and so is the router, trying to find the limits here 😄
rare-sapphire
rare-sapphire2y ago
You could build yourself a hook like this:
function useRouteSearch<
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
>(opts: StrictOrFrom<TFrom>) {
const search = useSearch(opts)
type RouteSearch = RouteById<TRouteTree, TFrom>['types']['searchSchema']
return search as RouteSearch
}

const routeSearch = useRouteSearch({ from: '/posts/post' })
function useRouteSearch<
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
>(opts: StrictOrFrom<TFrom>) {
const search = useSearch(opts)
type RouteSearch = RouteById<TRouteTree, TFrom>['types']['searchSchema']
return search as RouteSearch
}

const routeSearch = useRouteSearch({ from: '/posts/post' })

Did you find this page helpful?