How to get data type from onMutate function in useMutation
I'm doing optimistic updates using the technique which is documented here https://tanstack.com/query/latest/docs/framework/react/guides/optimistic-updates . I found that I'm using the same queries in multiple spots and want to extract the update code so that I don't have to copy and paste. I can't figure out the type of the
data
parameter in the onMutate function.
I've tried using type MutateData = Parameters<typeof api.task.createTask.useMutation>[0]
. The problem is that I can't then access the ['onMutate'] because it doesn't exist on there. Does anyone know how to get this?Optimistic Updates | TanStack Query React Docs
React Query provides two ways to optimistically update your UI before a mutation has completed. You can either use the onMutate option to update your cache directly, or leverage the returned variables to update your UI from the useMutation result.
Via the UI
12 Replies
https://trpc.io/docs/client/vanilla/infer-types
Would this be helpful?
Inferring Types | tRPC
It is often useful to access the types of your API within your clients. For this purpose, you are able to infer the types contained in your AppRouter.
Specifically,
That seems to do it! Thanks!
Can it be guaranteed that using the
inferRouterInputs<typeof taskRouter>['createTask']
(in my case) will always be the same type as what is passed into that onMutate function ?Hi, @G$Row, I just started building a project using tRPC with Next.js and I ran into this exact issue. I did some Googling and found this chat, so I figured I'd reach out. I followed the link @Mika posted but I get a TypeScript error. Here's my procedure.
Here's the TypeScript error I get. Please if any of you have come across this error, I'd appreciate it if you could explain what might be causing it.
Here's the list of my dependencies
You will keep seeing these kinds of errors and even more frustrating errors because you define the mutation function somewhere else
This means that you completely lose the context type information, which you tried to recover by inferring the router inputs
You should inline your functions and keep the logic inside the router file
Thanks so much for responding.
That's definitely a way to avoid the error. The only reason I wanted the put the mutation function in a separate file is just for better organization - the router file could get really long if I have lots of procedures.
Try not to fall into premature optimization trap. This is the perfect example of premature optimization
When it gets big, you'll refactor it
For now you're just making your life harder by letting typescript stand in the way between you and the app that you're building
FWIW, I have a production app running with dozens of routers, which in turn have dozens of procedures inside them. No big deal .
Gotcha. There's definitely a good reason behind starting out simple and refactoring as the project gets bigger.
Since you shared the type inference on tRPC's website and I couldn't replicate it without the annoying TS error, I just thought I'd point it out to let you know. My guess is it's likely something that has to do with my TS version (which was why I shared my list of dependencies)
I'll keep the procedures in the router file - and would try to keep an eye out for a solution.
It's not a ts bug, let me try to explain
The error you're getting is correct, this is a circular definition
When you write RouterInputs["auth"]["login"] typescript goes to the procedure and tries to read it's definition
But the auth login points to a function
It's hard to explain but if you think about it, it makes sense
When you try to retrieve the router inputs, typescript has to analyze the entire definition of that router, which includes the function definition ... It won't just read the
.input(loginSchema)
and be like ok, I'm done, here you go
If you really want to solve this problem your way, change your type to the following
But then you'll lose everything else in tRPC context, and you'll get a typescript error saying that context type is not compatible with loginOpts..Oh, that makes sense. Just one of the interesting behaviors of TS, i guess.
Thanks for explaining!