Unexpected return type when using `useQuery` from @trpc/react-query

545 views Asked by At

Full source here, for reference.

I'm fairly new to TypeScript, and brand new to NextJS (13.4) and tRPC. I'm working on building something to understand how the stack works.

For a quick bit of context, @trpc/react-query extends your server routes definition by giving you access to, among many other functions, useQuery. One of the options you can provide to useQuery as an argument is initialData, which allows you to pre-populate the results of the query.

The code where I invoke useQuery which is in src/app/_components/UserListClient.tsx

What I see in VS Code when I hover over initialData, underlined in red in the image above What I see in VS Code when I hover over initialData, underlined in red in the image above

What I see when hovering over initialUsers, which is being supplied as the value for initialData from the first screenshot

This is I see when hovering over initialUsers, which is being supplied as the value for initialData from the first screenshot

Looking into the error, I see that useQuery expects the data provided to be an array of users, except instead of expecting the users to have updatedAt and createdAt as dates, it expects strings.

However, my server router definition for the user.list procedure clearly defines the return type to have dates with a Date type, not a string, as shown in the screenshot below.

from my router definition

What is the problem? Why does useQuery know about the correct return type, with the odd specific exception where it appears to turn Date types into string types?

I tried inspecting the types that useQuery expects, but as I said, since I'm fairly new to TypeScript I found it quite difficult to trace back the types to see if at any point useQuery is casting my types, or anything like that. Not sure how to approach this, and not sure how to debug.

1

There are 1 answers

0
Christian Rodemeyer On

tRPC is using JSON to serialize data. As JSON does not have a Date type, JSON.stringify would convert a Date to a string:

JSON.stringify({createdAt: new Date()})
// {"createdAt":"2023-11-14T15:50:32.170Z"}

If you really want to use Date types instead of the string representation, have look at transformers using superjson:

https://trpc.io/docs/server/data-transformers#using-superjson