TRPC: Property 'useInfiniteQuery' does not exist on type '{ useQuery:
Asked Answered
T

4

7

TRPC Problem

i have this tweetRouter with a timeline query, which returns tweets and a NextCursor, but when i try to access useInfiniteQuery in my components a error show up.

** Property 'useInfiniteQuery' does not exist on type '{ useQuery: **

Translation: You're trying to access useInfiniteQuery on an object that doesn't contain it.

my component:

export function Timeline() {
  const data = trpc.tweet.timeline.useInfiniteQuery(
    {
      limit: 10,
    },
    {
      getNextPageParam: (lastPage) => lastPage.nextCursor,
    }
  );

  return (
    <Container maxW="xl">
      <CreateTweet />
      <Box
        borderX="1px"
        borderTop="1px"
        borderColor={useColorModeValue("gray.200", "gray.700")}
      >
        {data?.tweets.map((tweet) => {
          return <Tweet key={tweet.id} tweet={tweet} />;
        })}
      </Box>
    </Container>
  );
}

my tweet.ts router:

import { z } from "zod";
import { tweetSchema } from "../../../components/CreateTweet";
import { protectedProcedure, publicProcedure, router } from "../trpc";

export const tweetRouter = router({
  create: protectedProcedure.input(tweetSchema).mutation(({ ctx, input }) => {
    const { prisma, session } = ctx
    const { text } = input

    const userId = session.user.id

    return prisma.tweet.create({
      data: {
        text,
        author: {
          connect: {
            id: userId,
          }
        }
      }
    })
  }),
  timeline: publicProcedure.input(
    z.object({
      cursor: z.string().nullish(),
      limit: z.number().min(1).max(100).default(10)
    })
  ).query(async ({ ctx, input }) => {
    const { prisma } = ctx
    const { cursor, limit } = input

    const tweets = await prisma.tweet.findMany({
      take: limit + 1,
      orderBy: [
        {
          createdAt: "desc"
        }
      ],
      cursor: cursor ? { id: cursor } : undefined,
      include: {
        author: {
          select: {
            name: true,
            image: true,
            id: true
          }
        }
      }
    })

    let nextCursor: typeof cursor | undefined = undefined;

    if (tweets.length > limit) {
      const nextItem = tweets.pop() as typeof tweets[number];

      nextCursor = nextItem!.id;
    }

    return {
      tweets,
      nextCursor,
    };
  })
})

my prisma model:

model Tweet {
  id   String @id @default(cuid())
  text String

  author   User   @relation(fields: [authorId], references: [id])
  authorId String

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

and my autocompletion only shows up useQuery and useSuspenseQuery

i'm expecting to do a infinite scroll using useInfiniteQuery

Transfusion answered 3/12, 2022 at 3:20 Comment(1)
Did you find a solution? I'm having the same issue, using create t3-app default settings.Tar
T
4

I had to change the zod input validation property name from cursorId -> cursor

I also tried your timeline publicProcedure and it works fine on fresh create t3-app install

 getAll: publicProcedure
    .input(
      z.object({
        take: z.number().int(),
     // cursorId: z.string().nullish(),
        cursor: z.string().nullish(),
      }),
    ).query...
Tar answered 13/2, 2023 at 11:25 Comment(0)
B
2

Try setting compilerOptions.strict to true in your tsconfig.json. That fixed it for me.

Brachycephalic answered 26/1, 2023 at 13:30 Comment(0)
T
1

Just ran into this same issue using Next.js 13.4.1, TRPC 10.25.1, and Tanstack Query 4.29.5.

The TRPC docs page for useInfiniteQuery says:

"Your procedure needs to accept a cursor input of any type (string, number, etc) to expose this hook."

This dynamic modification of the type doesn't seem to be working correctly.

Setting "compilerOptions": { "strict": true } in your tsconfig.json does work, but comes with a lot of baggage and isn't something I wanted to enable in my codebase.

Instead the simplest solution I found was to arbitrarily redefine the type of the TRPC procedure to 'any', in your case this would look like:

const timelineProcedure: any = trpc.tweet.timeline;
const data = timelineProcedure.useInfiniteQuery(
  {
    limit: 10,
  },
  {
    getNextPageParam: (lastPage) => lastPage.nextCursor,
  }
);
Tridentum answered 23/8, 2023 at 13:56 Comment(0)
R
0

Unfortunately, you didn't share your root router in _app.ts

which should look like this

export const appRouter = router({
  tweet: tweetRouter,
});

export type AppRouter = typeof appRouter;

There should not be any problem if you follow this convention and I'm willing to help if you provide more information Because I've worked with useInfiniteQuery() without any issue.

Rosel answered 10/2, 2023 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.