tRPC Client-side Type Inference Issue with Nested Promises

232 Views Asked by At

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 the server:

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,
          };
        })
    );
  })

See in the comments code path (A) and (B).

On the server-side, everything works as expected for both paths. Path (B) works correctly on the client, too. But path (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?

0

There are 0 best solutions below