tRPC Client-side Type Inference Issue with Nested Promises

Hello everyone, I'm using tRPC for my TypeScript project and I've encountered an issue regarding type inference on the client-side. Here's the simplified code snippet from my server-side:
demoCode: publicProcedure.query(async () => {
return await Promise.all(
(
await Promise.resolve([{ name: "TEST" }])
)
.map(async (s) => {
const tables = await Promise.all(
// (A) Does NOT type correctly on client with:
// await prisma.X.findMany(...)

// (B) DOES type correctly with dummy data.
(
await Promise.resolve([{ id: 3 }, { id: 5 }])
).map((table) => ({
id: table.id,
}))
);

return {
...s,
tables: tables,
};
})
);
})
demoCode: publicProcedure.query(async () => {
return await Promise.all(
(
await Promise.resolve([{ name: "TEST" }])
)
.map(async (s) => {
const tables = await Promise.all(
// (A) Does NOT type correctly on client with:
// await prisma.X.findMany(...)

// (B) DOES type correctly with dummy data.
(
await Promise.resolve([{ id: 3 }, { id: 5 }])
).map((table) => ({
id: table.id,
}))
);

return {
...s,
tables: tables,
};
})
);
})
On the server-side, everything works as expected. Approach (B) works correctly on client and server. Approach (A) does not. On the server, the return type is correctly inferred, including the tables field. However, when I try to use this procedure on the client-side, the table field gets typed as any[] instead of the expected type. I understand that TypeScript's type inference may have limitations, particularly with complex, nested promises and data transformations. However, since the server-side types are inferred correctly, I was expecting tRPC to carry these types over to the client-side without the need for explicit typing. Is there something I'm missing here? Is there a better way to handle this without having to explicitly type the response on the server-side procedure? Any guidance or insight you could provide would be very appreciated. Thank you!
1 Reply
jlkravitz
jlkravitz•11mo ago
Following up here if anyone has thoughts... 🙂