eddeee888 / graphql-code-generator-plugins

List of GraphQL Code Generator plugins that complements the official plugins.
MIT License
44 stars 9 forks source link

Nested interface results in error #294

Closed Vishwaas closed 18 hours ago

Vishwaas commented 3 weeks ago

Describe the bug Lets say the schema had something like below:

interface INode {
 id: ID!
}

type User implements INode {
  name: string
  age: number
  location: Location
}

now I wanted to split it up as below:

interface INode {
 id: ID!
}

interface UserIFields implements INode {
  id: ID!
  name: string
  age: number
}

type User implements UserIFields {
  location: Location
}

This results in an unexpected types.generated.ts being generated. UserIFields ends up as

type UserIfields = {
name, age
}

and not

type UserIFields = INode & {
 name, age
}

Eg:

To Reproduce Steps to reproduce the behavior: _1.Setup a schema as above

  1. trying implementing a node field Eg:
    Query Main{
    node(id: ID!): INode,
    user: User
    }

Expected behavior

type UserIFields = INode & {
 name, age
}

Versions

Vishwaas commented 3 weeks ago

One more observation.

With the below interfaces:

interface INode {
 id: ID!
}

interface UserIFields implements INode {
  id: ID!
  name: string
  age: number
}

The below does not work

type User implements UserIFields {
  location: Location
}

but the below works:

type User implements UserIFields & INode {
  location: Location
}
eddeee888 commented 3 weeks ago

Hi @Vishwaas , Interfaces cannot implement other interfaces in a nested way you describe (Related SO answer)

However, you can implement multiple interfaces with a type (Related SO answer)

interface INode {
 id: ID!
}

interface UserIFields {
  name: String
  age: Int
}

type User implements INode & UserIFields {
  id: ID!
  name: String
  age: Int
}
Vishwaas commented 2 weeks ago

If you look at the accepted answer, it appears the latest graphql spec allows interfaces implementing other interfaces right? https://stackoverflow.com/questions/57888591/interface-extends-multiple-interfaces-in-graphql-schema

eddeee888 commented 2 weeks ago

Hi @Vishwaas 👋 You are right, it is allowed as of the latest GraphQL version.

I'm unable to see the issue you are reporting after running it through a CodeSandbox though. Here's the schema I had to update:

type Query {
    node(id: ID!): INode
}

interface INode {
 id: ID!
}

interface UserIFields implements INode {
  id: ID!
  name: String # Note: Updated from `string` to `String` from the issue
  age: Int # Note: Updated from `number` to `Int` from the issue
}

type User implements INode & UserIFields { # Note: Added INode here because both interfaces need to be here, otherwise it schema validation fails
  # Note: All the fields in the INode and UserIFields are needed to be here, otherwise schema validation fails.
  id: ID!
  name: String
  age: Int
}

And here's the generated types:

Screenshot 2024-06-16 at 9 51 59 pm

Note that the generated interface type UserIFields does not add its implementing type (INode) since all the fields are already generated.

You can check out this CodeSandbox to have a play.

eddeee888 commented 18 hours ago

Closing this since it seems to work fine in tests. Please let me know if it's still an issue and I'll re-open