Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum mismatch between typescript and graphql-codegen

I'm currently trying to wrap my head around the below issue, and not getting very far. Currently, I'm running an Apollo-Server as my graphQL server, have prisma2 configured with a postgres database, and am utilizing graphql-codegen to generate the types from my schema. Currently, I'm trying to update a model that has a many-to-many relationship and getting really strange typescript errors being thrown. I'm pretty sure I'm doing the update incorrectly, but the errors I'm seeing aren't helpful.

The following is the pertinent code snippets:

prisma.schema

model Permission {
  id       Int             @id @default(autoincrement())
  verb     PermissionVerb
  resource PermissionModel
  own      Boolean         @default(true)
  roles    Role[]
}
    
model Role {
  id          Int          @id @default(autoincrement())
  name        String
  permissions Permission[]
}

enum PermissionModel {
  USER
  ORDER
  CUSTOMER
  PERMISSION
  ROLE
}

enum PermissionVerb {
  CREATE
  READ
  UPDATE
  DELETE
}

permission.gql

extend type Mutation {
  updatePermission(input: UpdatePermissionInput): PermissionResult!
}

union PermissionResult = Permission | PermRoleNotFoundError

type Permission {
  id: Int!
  own: Boolean
  resource: PermissionModel!
  verb: PermissionVerb!
  roles: [Role]
}

type Role {
  id: Int!
  name: String!
  permissions: [Permission]
}

type PermRoleNotFoundError {
  message: String!
}

enum PermissionModel {
  USER
  ORDER
  CUSTOMER
  PERMISSION
  ROLE
}

enum PermissionVerb {
  CREATE
  READ
  UPDATE
  DELETE
}

and finally the offending code in the resolver:

updatePermission.ts

export const updatePermission: Resolver<
  ResolversTypes['UpdatePermissionInput'],
  {},
  Context,
  RequireFields<MutationUpdatePermissionArgs, never>
> = async (_parent, args, context, _info) => {
  const { id, verb, resource, own } = args.input

  const oldPermission = await context.prisma.permission.findFirst({
    where: { id },
    include: { roles: true }
  })

  const newPermission = await context.prisma.permission.update({
    where: { id },
    data: {
      id: oldPermission.id,
      verb: verb ? verb : oldPermission.verb,
      resource: resource ? resource : oldPermission.resource,
      own: own ? own : oldPermission.own,
    },
  })

  return newPermission
}

I'm getting the following typescript warning:

Type '(_parent: {}, args: RequireFields<MutationUpdatePermissionArgs, never>, context: Context, _info: GraphQLResolveInfo) => Promise<...>' is not assignable to type 'Resolver<UpdatePermissionInput, {}, Context, RequireFields<MutationUpdatePermissionArgs, never>>'.
Type '(_parent: {}, args: RequireFields<MutationUpdatePermissionArgs, never>, context: Context, _info: GraphQLResolveInfo) => Promise<...>' is not assignable to type 'ResolverFn<UpdatePermissionInput, {}, Context, RequireFields<MutationUpdatePermissionArgs, never>>'.
Type 'Promise<Permission>' is not assignable to type 'UpdatePermissionInput | Promise<UpdatePermissionInput>'.
Type 'Promise<Permission>' is not assignable to type 'Promise<UpdatePermissionInput>'.
Type 'Permission' is not assignable to type 'UpdatePermissionInput'.
Types of property 'verb' are incompatible.
Type 'import(\"/Users/jrichardson/Documents/Projects/wsw/node_modules/.prisma/client/index\").PermissionVerb' is not assignable to type 'import(\"/Users/jrichardson/Documents/Projects/wsw/backend/src/generated/graphql\").PermissionVerb'.
Type '\"CREATE\"' is not assignable to type 'PermissionVerb'.

I don't understand why it thinks the PermissionVerb is not assignable - as from what I can see from .prisma/client/index and the generated/graphql, both enums are identical. Not sure what I'm missing here.

Any help would be greatly appreciated! Thanks

like image 735
Joshua Richardson Avatar asked Nov 18 '25 01:11

Joshua Richardson


2 Answers

You can also tell graphql-codegen to create enums as const (string unions) by setting this in codegen.yml:

config:
  enumsAsConst: true
like image 126
Benny67b Avatar answered Nov 21 '25 08:11

Benny67b


For anyone coming to this question in 2024, I just ran into the same issue. I'm using this in my project:

"prisma": "^5.9.1"

"@graphql-codegen/cli": "^5.0.2",

"typescript": "^5.3.3"

And for me, the config that actually worked was enumsAsTypes: true not constEnums: true

Here is my config:

import { type CodegenConfig } from '@graphql-codegen/cli'

const config: CodegenConfig = {
  overwrite: true,
  schema: ['./schema/**/types.graphql', './schema/**/queries.graphql', './schema/**/mutations.graphql'],
  documents: ['./api/queries/**/**.ts', './api/mutations/**/**.ts'],

  generates: {
    '../../../web/src/graphql/': {
      preset: 'client',
    },

    './schema.graphql': {
      plugins: ['schema-ast'],
    },

    './types/schema.ts': {
      plugins: ['typescript'],
      config: {
        enumsAsTypes: true,
      },
    },
  },
  hooks: { afterAllFileWrite: ['prettier --write'] },
}

export default config
like image 28
Amir Avatar answered Nov 21 '25 10:11

Amir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!