type-graphql: Circular ref in Union Type breaks it

Describe the bug

When I use union type composed of fields that have circular references to each other, the schema doesn’t compile, throws TypeError: Cannot read property 'type' of undefined

To Reproduce

@ObjectType()
export class A {
  @Field(type => B)
  b: B;
}
@ObjectType()
export class B {
  @Field(type => A)
  a: A;
}
export type ABUnionType = A | B;

export const ABUnion = createUnionType({
  name: 'Union',
  types: [A, B],
  resolveType: value => {
    return PageType;
  },
});
@ObjectType()
export class C {
  @Field(type => ABUnionType)
  ab: ABUnion;
}

Expected behavior

This should compile and let me query on the union type.

Logs

api_1       |     TypeError: Cannot read property 'type' of undefined
api_1       | 
api_1       |       at unionMetadata.classTypes.map.objectType (../node_modules/type-graphql/dist/schema/schema-generator.js:64:138)
api_1       |           at Array.map (<anonymous>)
api_1       |       at types (../node_modules/type-graphql/dist/schema/schema-generator.js:64:59)
api_1       |       at resolveThunk (../node_modules/graphql/type/definition.js:381:40)
api_1       |       at defineTypes (../node_modules/graphql/type/definition.js:761:15)
api_1       |       at GraphQLUnionType.getTypes (../node_modules/graphql/type/definition.js:731:26)
api_1       |       at typeMapReducer (../node_modules/graphql/type/schema.js:307:23)
api_1       |       at typeMapReducer (../node_modules/graphql/type/schema.js:295:12)
api_1       |       at typeMapReducer (../node_modules/graphql/type/schema.js:330:22)
api_1       |       at typeMapReducer (../node_modules/graphql/type/schema.js:295:12)

Enviorment (please complete the following information):

  • OS: Mac OS (running Node image in Docker container)
  • Node 10.15.0
  • Package version 0.17.3
  • TypeScript version 3.0.1

Additional context

I am doing this within NestJS, I am not sure if this problem isn’t specific to it. I didn’t test this without it.

It compiles successfully once I remove the union field from type C, or when I remove one of the references from one of the types A or B.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 22 (6 by maintainers)

Most upvoted comments

I use a union in schema as follows, and works.

export const MultiEnityUnion = createUnionType({
  name: 'MultiEnityUnion', 
  types: () => [Property, BusinessProperty, Supplier, User, File, Contact],
  resolveType: value => {
    if ('contactType'  in value) return Contact
    if ('buildingType' in value) return Property
    if ('supplierType' in value) return Supplier
    if ('mimetype'     in value) return File
    if ('businessRole' in value) return User
    if ('property' in value && 'addressString' in value) return BusinessProperty
    return undefined
  }
})
@ObjectType()
export class Note extends GlobalFields {

  @Field() 
  @prop()
  body: string
  
  @Field() 
  @prop()
  sticky: boolean

  @Field(type => MultiEnityUnion, {nullable: true})
  @prop({ required: true, refPath: 'entityRef' })
  entity: Ref<Property | BusinessProperty | Contact | Supplier | User | File>
 
  @Field(type => EntitiesEnum, {nullable: true})
  @prop({required: true, enum: Object.values(EntitiesEnum), index: true})
  entityRef: EntitiesEnum

  @Field(type => [FileRef])
  @arrayProp({_id: false, items: FileRef})
  files: FileRef[]
  
} 

export const NoteModel = getModelForClass(Note)

@gimyboya The error comes from Object._buildPropMetadata (D:\Grainer\Ethis\Projects\dashboard-backend\node_modules\@typegoose\typegoose\lib\prop.js:162:19) so I can’t do anything with that typegoose error.

@gimyboya , In my instance it was a node issue with circular dependency in the end. you may have a similar issue.