A simple tRPC transformer combining superjson with Decimal.js.
yarn add trpc-transformer
or
npm i trpc-transformer
- Add it to your
initTRPC
:
import { initTRPC } from '@trpc/server';
import transformer from 'trpc-transformer';
export const t = initTRPC.create({ transformer });
- ...and to your tRPC client:
import transformer from 'trpc-transformer';
const client = trpc.createClient({
links: [
httpBatchLink({
// ...
transformer,
}),
],
});
Assuming you have an appRouter.ts
like this on the server-side:
import { initTRPC } from '@trpc/server';
import transformer from 'trpc-transformer';
import prisma from '~/lib/server/prisma';
const t = initTRPC.create({ transformer });
export const appRouter = t.router({
users: t.procedure.query(() =>
prisma.user.findMany({
select: {
id: true,
name: true,
createdAt: true,
accounts: {
select: { iban: true, balance: true },
},
},
})
)
});
export type AppRouter = typeof appRouter;
...then, you'll have your data correctly serialized/deserialized on the client-side:
import Decimal from 'decimal.js';
import { trpc } from '~/lib/client/trpc';
const usersQuery = trpc.users.useQuery();
console.log('Account createdAt is Date:', usersQuery.data?.[0].createdAt instanceof Date); // 👈 true
console.log('Account balance is Decimal.js:', usersQuery.data?.[0].accounts[0].balance instanceof Decimal); // 👈 true
Note
The above example assumes a Next.js project with a lib/client/trpc.ts
file like this:
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from 'swapp.ro.server';
export const trpc = createTRPCReact<AppRouter>();
...and a layout.tsx
file like this:
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { httpBatchLink } from '@trpc/client';
import { useState } from 'react';
import transformer from 'trpc-transformer';
import { trpc } from '~/lib/client/trpc';
export default function DynamicLayout({ children }: Readonly<{ children: React.ReactNode }>) {
const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
httpBatchLink({
url: 'your api url',
transformer,
}),
],
})
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</trpc.Provider>
);
}
See trpc.io/docs/data-transformers and github.com/blitz-js/superjson.
The ISC License.