hayes / pothos

Pothos GraphQL is library for creating GraphQL schemas in typescript using a strongly typed code first approach
https://pothos-graphql.dev
ISC License
2.28k stars 153 forks source link

Prisma `t.relatedConnection` Failing to Throw Typing Errors #1179

Closed arimgibson closed 3 months ago

arimgibson commented 3 months ago

Apologies if this is an issue with my setup/my TypeScript vs an issue with Pothos. Also open to feedback if there's a better way to DRY the logic for filtering via args and Prisma while we wait for the Prisma Utils plugin to be prod-ready!

Repro: https://github.com/arimgibson/pothos-prisma-query-where-repro

See schema.ts in the repro. When using properties generated by a function into the query.where section of t.relatedConnection, properties that aren't part of the Prisma schema should throw an error as the return type of query doesn't match something that can be queried in Prisma. However, no errors are thrown.

export const commentFilterArgs = builder.args((t) => ({
  type: t.field({
    type: CommentType,
  }),
}));

export function commentFilterQueryWhere(args: InputShapeFromFields<typeof commentFilterArgs>): Prisma.CommentWhereInput {
  return {
    type: args.type ?? undefined,
    // Error is thrown here as Prisma knows this isn't a field on Comment
    foo: "bar",
  };
}

builder.prismaNode("User", {
  id: { field: "id" },
  fields: (t) => ({
    firstName: t.exposeString("firstName"),
    lastName: t.exposeString("lastName"),
    fullName: t.string({
      resolve: (user) => `${user.firstName} ${user.lastName}`,
    }),
    posts: t.relation("posts"),
    comments: t.relatedConnection("comments", {
      cursor: "id",
      // Example that doesn't throw error when it should
      query: (_args, _context) => ({
        where: {
          ...commentFilterQueryWhere(_args),
        },
      }),

      // Second example that doesn't throw error when it should
      // query: (_args, _context) => ({
      //   where: {
      //     foo: "bar",
      //     ...commentFilterQueryWhere(_args),
      //   },
      // }),

      // Example that throws error
      // query: (_args, _context) => ({
      //   where: {
      //     foo: "bar",
      //   },
      // }),
    }),
  }),
});
hayes commented 3 months ago

This is a known limitation of typescript. Typescript doesn't really have a built in mechanism to limit what keys can be passed in. There are technically things you can do to cause this to error, but it's often not worth the added complexity

arimgibson commented 3 months ago

This is a known limitation of typescript. Typescript doesn't really have a built in mechanism to limit what keys can be passed in. There are technically things you can do to cause this to error, but it's often not worth the added complexity

Ah, gotcha. Yep, just tried with a regular object and same thing; sorry I didn't catch that earlier. Unfortunately this throws a runtime error with Prisma but manageable as I can set the return type of the function that generates those where fields.

Thanks!!