Search code examples
typescriptgraphqlprisma

Prisma with GraphQL - how to provide an explicit type for a specified array of strings - unique naming issue


I am trying to figure out how to specify an explicit type for a field, that is defined in a prisma schema as having an enum value.

In my schema I have:

enum Category {
  CHANGE
  OPTION 
  OTHER
}

and a model that uses Category as follows:

model Issue {
  id          String           @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
  title       String
  description String
  category    Category
  Template    Template[]
  createdAt   DateTime    @default(now()) @db.Timestamptz(6) 
  updatedAt   DateTime    @default(now()) @updatedAt @db.Timestamptz(6)
  User        User[]
}

Then in the back end, I have a model:

import * as Prisma from "@prisma/client"

import { Field, ObjectType } from 'type-graphql'
import { BaseModel } from "../shared/base.model"
// - I tried this but it didn't help: import { Category } from "@generated"



@ObjectType()
export class Issue extends BaseModel implements Prisma.Issue {

    @Field()  
    title: string

    @Field()
    description: string

    @Field(() => Category)
    category: Prisma.Category
    
    
}

and an input file that both define 'category', I think I'm providing the right type, by referencing the Prisma enum (not sure if instead I'm supposed to reference the generated types).

import { IsNotEmpty } from "class-validator"
import { Field, InputType } from "type-graphql"
import { Issue } from '../issue.model'
import * as Prisma from "@prisma/client"


@InputType()
export class IssueInput implements Partial<Issue> {
    @Field()
    @IsNotEmpty()
    title: string

    @Field()
    @IsNotEmpty()
    description: string

    @Field()
    @IsNotEmpty()
    category: Prisma.Category

    @Field()
    @IsNotEmpty()
    userId: string



}

When I try to run yarn dev with this, I get an error that says:

NoExplicitTypeError: Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'category' of 'IssueInput' class

How can I figure out how to give a type to category in the IssueInput class? I can't find an example of how to do this.

I tried adding: registerEnumType to both the IssueInput definition, and the Issue Model, using the idea set out below:

import { IsNotEmpty } from "class-validator"
import { Field, InputType, registerEnumType } from "type-graphql"
import { Issue } from '../issue.model'
import * as Prisma from "@prisma/client"


registerEnumType(Prisma.Category, {
  name: "Category", // this one is mandatory
  description: "Issue Category", // this one is optional
});


@InputType()
export class IssueInput implements Partial<Issue> {
    @Field()
    @IsNotEmpty()
    title: string

    @Field()
    @IsNotEmpty()
    description: string

    @Field()
    @IsNotEmpty()
    category: Prisma.Category

    @Field()
    @IsNotEmpty()
    userId: string



}

I still get an error saying:

NoExplicitTypeError: Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'category' of 'IssueInput' class. at Object.findType

When I try it like below, I get a console error that says Error: Schema must contain uniquely named types but contains multiple types named "Category". I only have one Category in the schema file.

Within my terminal, the error is expressed differently, it says:

Property 'category' in type 'IssueInput' is not assignable to the same property in base type 'Partial'. Type 'Category' is not assignable to type 'Category | undefined'. Type '"CHANGE"' is not assignable to type 'Category | undefined'.

import { IsNotEmpty } from "class-validator"
import { Field, InputType, registerEnumType } from "type-graphql"
import { Issue } from '../issue.model'
import * as Prisma from "@prisma/client"


registerEnumType(Prisma.Category, {
  name: "Category", // this one is mandatory
  description: "Issue Category", // this one is optional
});


@InputType()
export class IssueInput implements Partial<Issue> {
    @Field()
    @IsNotEmpty()
    title: string

    @Field()
    @IsNotEmpty()
    description: string

    @Field(type => Prisma.Category)
    @IsNotEmpty()
    category: Prisma.Category
    // category: Prisma.Category | undefined -- this also does not solve the problem  


    @Field()
    @IsNotEmpty()
    userId: string



}

Solution

  • You need to register the enum with type-graphql.

    import { registerEnumType } from "type-graphql";
    
    registerEnumType(Prisma.Category, {
      name: "Category", // this one is mandatory
      description: "Issue Category", // this one is optional
    });