Replies: 5 comments 5 replies
-
we are always open to contributions. so please by all means share a solution for what you consider to be a problem here. |
Beta Was this translation helpful? Give feedback.
-
This feedback is so easily given without a solution. I remember having similar sentiment until I explored many alternatives which feel categorically much worse: importing the router/routeTree or its types into literally every file of your application. There are ways around Monorepo setups, which @TkDodo is working on making public. As for the “you could make a mistake”, yes you could. But you’d quickly realize your mistake. |
Beta Was this translation helpful? Give feedback.
-
You are right, I don’t really have a good solution in mind right now, that’s why I’ve opened it as a discussion instead of a feature request. When looking at other frameworks and library, the approach how my-app-router.ts: import { createRouter } from '@tanstack/router';
const { Link, useNavigate, router, /* ... */} = createRouter({ /* ... */});
export { Link, useNavigate, router, /* ... */ } MyComponent.ts import { useNavigate } from './my-app-router.js'
export function MyComponent(props) {
const navigate = useNavigate();
return <div onClick={() => navigate({ to: '/' })}>foo</div>
} I know this is not as nice and ergonomic to use as importing those APIs directly from Another approach would be to pass the There might be even more and better approaches than those two, that’s basically the goal of this discussion to check if someone has a good idea to make this part of |
Beta Was this translation helpful? Give feedback.
-
Thanks a bunch for discussing this. We recently stumbled upon a similar situation, where we are trying to separate route trees for users and admins and thus need two routers. Surely, we could split the route trees into two apps, and just go back to one router per app, but we wanted to give this a shot, and as well, would love to not have global types. @tannerlinsley is the router "registration" a recommendation or strictly required to make the best use of tanstack router?
🤘 Thanks a bunch to you and your team for supporting the community the way you do. |
Beta Was this translation helpful? Give feedback.
-
Might not be the best place but it deals with type-safety We recently evaluated the tanstack-router usage in the monorepo project, in which each feature is a separate module as a separate package and different teams maintain them. Also, each module should be responsible for maintaining its routes with the upper-level module specifying the root-level route for that module. With this, we accomplish that each team can maintain the module's internal routing however they want, and it works with react-router v6. Tanstack example approach for monorepo is to have one global route module and have everyone depend on it but in our opinion, it can't work for us as part of the module-specific logic has to be defined in that module and we need to update each route so it knows what the render. Even if we decided to give this a chance, the main issue is with validateSearchParams. It can't be updated after definition and we would have to define the schema inside the router module which in some cases will create a circular dependency between modules (the global router package doesn't need to know anything about the column names to validate search params, that should be part of the specific module). Maybe we might find a workaround for this and have additional low-level packages per module but it would be a pain in the ... to maintain everything and define strict boundaries, "just" to get type-safety on the router. I was first thinking about routers slicing and then combining them into a general router, something similar to what redux-toolkit is doing for redux state, but I don't think it would be possible for the router to inherit details from parent routes, mainly search params, and cross-module navigation probably something more. Maybe I missed something and someone can get something of that idea so better to post it. Is there any recommended approach to achieve this separation for route definition and still get type safety? |
Beta Was this translation helpful? Give feedback.
-
According to the documentation tanstack router requires the use of extending the existing
Register
interaface with the type of the custom router in order to unlock full type-safety.I think this claim is incorrect. And it even makes things more unsafe than safe. Because it is basically a global type assertion meaning every exposed function from
@tanstack/router
is convinced to think the router type is always the one that has been registered. But there is no way, that the registering itself can be guaranteed to be done correctly. So if the wrong type is registered, then all the type ins components like<Link />
or in functions likeuseNavigation()
are incorrect. This is not only an issue when registering incorrect types, but when working with multiple router instances which have different setup and thus different types. In my use-case for example I create a different router in my unit tests which only one or two example routes to test something. But according to the types of the created test routers, methods likerouter.navigate()
indicate via their type that routes could be used that don’t exist on the test router but only on the actual app router.I could also imagine other use-cases where someone want to have multiple router instances, for example in a monorepo where multiple different pages are deployed from (e.g. an admin-panel and a customer-facing interface).
So I think, if
@tanstack/router
really wants to become a fully type-safe router it needs to get rid of this approach relying on global registering of types.Beta Was this translation helpful? Give feedback.
All reactions