Looks like there's not a way to control the input type of search params. calls to navigate still require search params even if they are marked as optional and resolved with default or catch. Unless I'm missing something. Stackblitz with example: https://stackblitz.com/edit/tanstack-router-vkzaga?file=src%2Froutes%2Fposts.tsx
import * as React from 'react';
import { createFileRoute, Link, Outlet } from '@tanstack/react-router';
import { useSuspenseQuery } from '@tanstack/react-query';
import { postsQueryOptions } from '../postsQueryOptions';
import { z } from 'zod';
const searchSchema = z.object({
foo: z.number().default(1),
fiz: z.string().optional(),
});
type ZSearchInput = z.input<typeof searchSchema>;
type ZSearchOutput = z.output<typeof searchSchema>;
export const Route = createFileRoute('/posts')({
validateSearch: (search: ZSearchInput) => searchSchema.parse(search),
loader: ({ context: { queryClient } }) =>
queryClient.ensureQueryData(postsQueryOptions),
component: PostsComponent,
});
function PostsComponent() {
const navigate = Route.useNavigate();
const postsQuery = useSuspenseQuery(postsQueryOptions);
const posts = postsQuery.data;
navigate({
to: '/posts',
search: {
// I would expect foo and fiz to both be optional here. Should follow type of ZSearchInput
},
});
return (
<div className="p-2 flex gap-2">
....
</div>
);
}