Coercing date types from the server to the client #5699
-
I have a zod type that uses pipe and coerce to parse a string type into a date on the Server. When it gets used by the client, the type (both runtime and typescript) changes to a string. Is it possible to pass a Date type over the wire and have trpc re-coerce it to a Date on the client? I created a minimal example here on stackblitz to illustrate. Basically on the server we have a zod type that is used to parse a fake API with dates represented as strings Server side api// SERVER SIDE API
import { z } from 'zod';
const DateSchema = z.string().pipe(z.coerce.date());
const Widget = z.object({
id: z.number(),
name: z.string(),
lastUpdate: DateSchema,
});
const ListWidgetResponse = z.array(Widget);
type ListWidgetResponse = z.infer<typeof ListWidgetResponse>;
const fakeApiResponse = [
{
id: 1,
name: 'bigWidget',
lastUpdate: '2024-04-26T23:19:46Z', // string that gets coerced to a Date object
},
];
export function listWidgets(): ListWidgetResponse {
const widgets = ListWidgetResponse.parse(fakeApiResponse);
// -----------------------------------------------------
// Both the runtime type and typescript type of lastUpdate on the Server is 'Date' because of coercion
// -----------------------------------------------------
const { lastUpdate } = widgets[0];
return widgets;
} Server side routerimport { createHTTPServer } from '@trpc/server/adapters/standalone';
import { z } from 'zod';
import { listWidgets } from './api.js';
import { publicProcedure, router } from './trpc.js';
const appRouter = router({
listWidgets: publicProcedure.query(() => listWidgets()),
});
// Export type router type signature, this is used by the client.
export type AppRouter = typeof appRouter;
const server = createHTTPServer({
router: appRouter,
});
server.listen(3000); Client side consumerimport { createTRPCClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '../server/index.js';
// Initialize the tRPC client
const trpc = createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: 'http://localhost:3000',
}),
],
});
const widgets = await trpc.listWidgets.query();
// -----------------------------------------------------
// Both the runtime type and typescript type of lastUpdate on the client is 'string'
// -----------------------------------------------------
const { lastUpdate } = widgets[0]; |
Beta Was this translation helpful? Give feedback.
Answered by
Nick-Lucas
May 3, 2024
Replies: 1 comment 1 reply
-
You need to set up a transformer, so can take a look at our docs on this 🙂 |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
mkellyclare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You need to set up a transformer, so can take a look at our docs on this 🙂