Skip to content

FullSearchSchema incorrect if routes have conflicting search schemas #859

@schiller-manuel

Description

@schiller-manuel

Motivation

I want to write a hook that expects a certain search schema.
This hook may only accept certain route ids, so I filter the all routes by their search schema like this:

export type RouteIdsMatchingSearchSchema<SearchSchema> = {
  [R in ParseRoute<
    RegisteredRouter['routeTree']
  > as R['types']['fullSearchSchema'] extends SearchSchema
    ? R['id']
    : never]: true;
};

const searchSchema = z.object({page: z.number().catch(1), filter: z.string().catch('')});
type RequiredSearchSchema = z.infer<typeof searchSchema>;
type FilteredRoutes = RouteIdsMatchingSearchSchema<RequiredSearchSchema>;
type FilteredRouteIds = keyof FilteredRoutes;

interface UseFilterPaginationParams {
  from: FilteredRouteIds;
}

function useFilterPagination({from} : UseFilterPaginationParams) {
  const navigate = useNavigate({from});
  
  const onPrevious = useCallback(
    () =>
      navigate({
        search: (prev) => ({
          ...prev,
          page: prev.page - 1,
        }),
        params: (prev) => prev,
      }),
    [navigate],
  );
}

Screenshot 2023-12-19 at 02 10 35

This fails with Type '(prev: any) => any' is not assignable to type 'never'.ts(2322) as soon as there are routes that have "contradicting" search schemes, e.g.:

const anotherRoute = new Route({
  getParentRoute: () => rootRoute,
  path: '/another',
  validateSearch: searchSchema.extend({foo: z.enum(['another', 'route']).catch('another')}),
  component: () => null,
})

const postRoute = new Route({
  getParentRoute: () => postsRoute,
  path: '$postId',
  validateSearch: searchSchema.extend({foo: z.enum(['posts', 'foo']).catch('posts')}),
  errorComponent: PostErrorComponent,
  loader: ({ context: { queryClient }, params: { postId } }) =>
    queryClient.ensureQueryData(postQueryOptions(postId)),
  component: PostRouteComponent,
})

Both routes match the required search schema and both routes define a parameter foo with different types.

Describe the bug

The bug occurs if some routes have "conflicting" search schemas, i.e. they define at least one param with a different type.
Then FullSearchSchema is calculated to be {} and all mechanism that depend on this type subsequently fail.

Your Example Website or App

https://codesandbox.io/p/devbox/flamboyant-goldberg-cyzvdp?file=%2Fsrc%2Fmain.tsx%3A281%2C12

Steps to Reproduce the Bug or Issue

  1. go to https://codesandbox.io/p/devbox/flamboyant-goldberg-cyzvdp?file=%2Fsrc%2Fmain.tsx%3A281%2C12
  2. go to line 62 and check that FullSearchSchema is {}
  3. go to line 72 and check the error

Expected behavior

Routes should be able to define "conflicting" search schemas without causing the whole type safety to break.

Platform

  • OS: macOS
  • Browser: Firefox
  • Version: 120

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions