MichalLytek / typegraphql-prisma

Prisma generator to emit TypeGraphQL types and CRUD resolvers from your Prisma schema
https://prisma.typegraphql.com
MIT License
891 stars 113 forks source link

Prisma 5 - incompatible type for cursor property #406

Open ramiel opened 1 year ago

ramiel commented 1 year ago

Describe the Bug With the new prisma 5 version the type produced by code generation is wrong for the cursor type. This only happens with cursor, not the other properties. In the image below FindManyCaptionArgs comes from the type in the generate file packages/prisma/dist/@generated/resolvers/crud/Caption/args/FindManyCaptionArgs.d.ts

image

To Reproduce Try to use the types generated from the package for find operations

Expected Behavior The type should match

Logs

Type 'import("[...]@generated/resolvers/inputs/CaptionWhereUniqueInput").CaptionWhereUniqueInput | undefined' is not assignable to type 'import("[...]/node_modules/.pnpm/@prisma+client@5.0.0_prisma@5.0.0/node_modules/.prisma/client/index").Prisma.CaptionWhereUniqueInput | undefined'.
  Type 'CaptionWhereUniqueInput' is not assignable to type 'CaptionWhereUniqueInput | undefined'.
    Type 'CaptionWhereUniqueInput' is not assignable to type '{ id: string | CaptionProjectIdInterimIdTargetLanguageCompoundUniqueInput; projectId_interimId_targetLanguage: string | CaptionProjectIdInterimIdTargetLanguageCompoundUniqueInput; } & { ...; }'.
      Type 'CaptionWhereUniqueInput' is not assignable to type '{ id: string | CaptionProjectIdInterimIdTargetLanguageCompoundUniqueInput; projectId_interimId_targetLanguage: string | CaptionProjectIdInterimIdTargetLanguageCompoundUniqueInput; }'.
        Types of property 'id' are incompatible.
          Type 'string | undefined' is not assignable to type 'string | CaptionProjectIdInterimIdTargetLanguageCompoundUniqueInput'.
            Type 'undefined' is not assignable to type 'string | CaptionProjectIdInterimIdTargetLanguageCompoundUniqueInput'.ts(2322)

Environment (please complete the following information):

MichalLytek commented 1 year ago

Can you share related part of your Prisma schema?

ramiel commented 1 year ago

This is the relevant section

model Caption {
  /// @TypeGraphQL.omit(input: ["create"])
  id                String            @id @default(auto()) @map("_id") @db.ObjectId
  /// @TypeGraphQL.omit(input: true)
  createdAt         DateTime          @default(now())
  /// @TypeGraphQL.omit(input: true)
  updatedAt         DateTime          @updatedAt
  /// @TypeGraphQL.omit(input: true)
  projectId         String            @db.ObjectId
  interimId         String?
  isFinal           Boolean
  text              String
  sourceLanguage    String
  targetLanguage    String
  timestampStart    BigInt
  timestampEnd      BigInt?
  /// @TypeGraphQL.omit(input: true)
  status            CaptionStatus
  captioner         User?             @relation(fields: [captionerId], references: [id], onDelete: SetNull, onUpdate: SetNull)
  project           Project           @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade)
  revisions         CaptionRevision[]
  currentRevisionId String?
  captionerId       String?           @db.ObjectId

  @@unique([projectId, interimId, targetLanguage])
  @@index([projectId, targetLanguage])
  @@index([timestampStart(sort: Desc)])
}
ramiel commented 1 year ago

I have the same error for any model though, so I don't think it's related to this in particular

MichalLytek commented 1 year ago

I've encountered this for models with multi-columns unique indexes. This breaks TS typings because in Prisma 5.0 they use a TS trick to check if user provides either a primary key or the unique combination of fields. However, in GraphQL we can't enforce such constraints, so it now yells in compile-time that something is wrong.

ramiel commented 1 year ago

I see. Any workaround we can put in place? I guess I can omit 'cursor' from my type, but this is not a global solution. Maybe the type of cursor should be any while in graphql it keeps all the possible keys without enforcing just one?

shawnjones253 commented 1 year ago

related to this? https://github.com/prisma/prisma/issues/20619

chrisbruford commented 1 year ago

We're seeing this with a model with only one unique field:

model RedactedModelName {
  id                String                   @id @default(uuid())
  redactedId        String
  redactedField     RedactedField            @relation(fields: [redactedId], references: [id])
  userId            String
  user              User                     @relation(fields: [userId], references: [id])
  reasonId          String
  reason            DisputedReason           @relation(fields: [reasonId], references: [id])
  createdAt         DateTime                 @default(now()) @db.Timestamptz
  updatedAt         DateTime                 @updatedAt @db.Timestamptz
  status            Status                   @default(OPEN)
  notes             String?
}

The generated FindManyRedactedModelNameArgs type is not compatible with the expected type for prisma.redactedModel.findMany

I've added a hack around this for now:

export type TypegraphqlWorkAround<T> = T & { cursor?: any };

and then just declare/assert with:

TypegraphqlWorkAround<FindManyRedactedModelNameArgs>