Obtaining typescript type of trpc or react-query's useQuery result "data" property

2k Views Asked by At

In my React + TRPC application, I call const { data: promotion } = trpc.promotions.getPromotion.useQuery({ id: promotionId }) in the client-side. promotion's type is detected by looking at the return type of the actual server-side code:

  getPromotion: protectedProcedure
    .input(z.object({ id: z.string() }))
    .query(async({ ctx, input }) => {
      const promotion = await ctx.prisma.promotion.findUniqueOrThrow({
        where: {
          id: input.id
        }
      })

      return {
        ...promotion,
        canModify: false
      }
    })

However, I want to use this same type in an interface another component:

interface Example {
   promotion: TheDetectedTypeOfGetPromotionReturn??
}

The problem is, I can't find a way to "extract" the type I need.

I thought maybe I could use ReturnType<typeof trpc.promotions.getPromotion.useQuery>['data'] but that just returns unknown. Yet, data is a valid type on the returned object.

Here's where the useQuery code is defined: https://github.com/trpc/trpc/blob/9e84d4d9c43de3272aa84bf4110e31e47dc5dda6/packages/react-query/src/shared/hooks/createHooksInternal.tsx#L427

Here's the query base type it uses from react-query: https://github.com/TanStack/query/blob/1614c31f84744c62b5bee8f2ff97fc15a1652e86/packages/query-core/src/types.ts#L367

2

There are 2 best solutions below

1
On

I managed to do it like this

import {type UseTRPCQueryResult} from '@trpc/react query/shared'
import {type inferRouterOutputs} from '@trpc/server'
import {type TRPCClientErrorLike} from '@trpc/react-query'

type YourType = UseTRPCQueryResult<inferRouterOutputs<AppRouter>['promotions']['getPromotions'], TRPCClientErrorLike<AppRouter>>['data']
0
On

From the official documentation, you can use something like:

import type { inferRouterOutputs } from '@trpc/server';
import type { AppRouter } from './server';
 
type RouterOutput = inferRouterOutputs<AppRouter>;

type OutputExample = RouterOutput['someRoute']['someQuery'];