T
TanStack11mo ago
optimistic-gold

Route implicitely has type 'any' because of loader

I have the following code:
export const Route = createFileRoute(
"/_layout/_adminPermission/admin/committees/$slug",
)({
loader: ({ context: { queryClient, auth }, params: { slug } }) =>
queryClient.ensureQueryData(
committeesDetailQueryOptions(auth.getToken, slug),
),
component: () => (
<Suspense fallback={<></>}>
<Page />
</Suspense>
),
});
export const Route = createFileRoute(
"/_layout/_adminPermission/admin/committees/$slug",
)({
loader: ({ context: { queryClient, auth }, params: { slug } }) =>
queryClient.ensureQueryData(
committeesDetailQueryOptions(auth.getToken, slug),
),
component: () => (
<Suspense fallback={<></>}>
<Page />
</Suspense>
),
});
This results in Route being 'any'. Making loader async/await does not change this. When I remove loader, the type of Route is inferred correctly and the error disappears. There are also routes that have a loader that do work correctly. I would likt to add more relevant information, but not sure what could be useful. Anyone can point me in the right direction for what I might be doing wrong? Thanks!
5 Replies
wise-white
wise-white11mo ago
ideally, share a complete minimal example by forking one of the existing examples on stackblitz you can try this:
export const Route = createFileRoute(
"/_layout/_adminPermission/admin/committees/$slug",
)({
loader: async ({ context: { queryClient, auth }, params: { slug } }) => {
await queryClient.ensureQueryData(
committeesDetailQueryOptions(auth.getToken, slug),
)},
component: () => (
<Suspense fallback={<></>}>
<Page />
</Suspense>
),
});
export const Route = createFileRoute(
"/_layout/_adminPermission/admin/committees/$slug",
)({
loader: async ({ context: { queryClient, auth }, params: { slug } }) => {
await queryClient.ensureQueryData(
committeesDetailQueryOptions(auth.getToken, slug),
)},
component: () => (
<Suspense fallback={<></>}>
<Page />
</Suspense>
),
});
here the loader does not return but simply awaits. (of course you cannot use useLoaderData then, but you would access this via use(Suspense)Query) most likely the return type of your query cannot be inferred correctly, so this solution works around that
optimistic-gold
optimistic-goldOP11mo ago
Turns out that in one of the parent layouts (_adminPermission) in this case, I added a return statement to the beforeLoad function, which meant the type of the route was not correctly inferred and subsequently the ones of the child routes couldn't either. So the end the mistake was not in the code provided. I'll think of recreating the issue next time in a sandbox. Thanks for the help anyway!
wise-white
wise-white11mo ago
can you show how that looked like? I am wondering if we could detect this e.g. via an eslint rule
optimistic-gold
optimistic-goldOP11mo ago
Sure, although I found the issue because there already was an error in the code. The code for the ._layout._adminPermission file was:
import { Outlet, redirect } from "@tanstack/react-router";
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/_layout/_adminPermission")({
beforeLoad: async ({ context, location, ...ctx }) => {
if (context.auth.orgRole != "org:admin") {
throw redirect({
to: "/not-permitted",
search: {
// Use the current location to power a redirect after login
// (Do not use `router.state.resolvedLocation` as it can
// potentially lag behind the actual current location)
redirect: location.href,
},
});
}
return {
context,
location,
...ctx,
};
},
component: () => <Outlet />,
});
import { Outlet, redirect } from "@tanstack/react-router";
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/_layout/_adminPermission")({
beforeLoad: async ({ context, location, ...ctx }) => {
if (context.auth.orgRole != "org:admin") {
throw redirect({
to: "/not-permitted",
search: {
// Use the current location to power a redirect after login
// (Do not use `router.state.resolvedLocation` as it can
// potentially lag behind the actual current location)
redirect: location.href,
},
});
}
return {
context,
location,
...ctx,
};
},
component: () => <Outlet />,
});
The error that was shown on beforeLoad was 'beforeLoad' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions I originally missed this because I messed up my eslint config and just failed to realize that the type issue could come from one of the parent routes as well.
wise-white
wise-white11mo ago
I cannot spot the error here, why wouldn't you be able to return this? (although there would be no need since you are just returning what you got passed in ...)

Did you find this page helpful?