Graphql-code-generator: Nested interfaces results in fragment fields getting picked too widely

Created on 14 Dec 2020  路  6Comments  路  Source: dotansimha/graphql-code-generator

To Reproduce

Sandbox link: https://codesandbox.io/s/sad-galileo-ljeo2?file=/types.ts

Steps to reproduce the behavior:

  1. Create an interface Bthat extends an existing interface A
  2. Do a GraphQL query where you use a (inline) fragment for B where you pick some fields specific to B
  3. Generate the types for that query
  4. There will be a Pick<> that tries to pick B fields from types only implementing A.

Describe the bug

If one has a schema with:

interface Entity {
  id: ID!
}

interface NamedEntity implements Entity {
  id: ID!
  name: String!
}


paired with the rest of the fields needed to have a complete schema

type Query {
    entity(id: ID!): Entity!
}

interface Entity {
  id: ID!
}

interface NamedEntity implements Entity {
  id: ID!
  name: String!
}

type Session implements Entity {
  id: ID!
  data: String!
}

type User implements NamedEntity & Entity {
  id: ID!
  name: String!
}

And then does a query like:

query entity {
    entity(id: 1) {
        id
        ... on NamedEntity {
            name
        }
    }
}

Then the generated type will contain the following erroneous code:

export type EntityQuery = (
  { __typename?: 'Query' }
  & { entity: (
    { __typename?: 'Session' }
    & Pick<Session, 'name' | 'id'>
  ) | (
    { __typename?: 'User' }
    & Pick<User, 'name' | 'id'>
  ) }
);

Where it tries to pick a NamedEntity field name from the non-NamedEntity type Session, Pick<Session, 'name' | 'id'>, rather than correctly just pick id.

After checking back and forth I believe that this is caused by one interface extending another and that they somehow gets mixed up then.

bug plugins waiting-for-release

Most helpful comment

@dotansimha Yes, should be pretty straight-forward to implement a failing test case (based on the information provided by @voxpelli) and adjust the implementation. I can take a look over the next few days!

All 6 comments

Thank you for reporting it @voxpelli . It seems like we somehow collects fields incorrectly in this use-case.
I assume your intended output is:

export type EntityQuery = (
  { __typename?: 'Query' }
  & { entity: (
    { __typename?: 'Session' }
    & Pick<Session, 'id'>
  ) | (
    { __typename?: 'User' }
    & Pick<User, 'name' | 'id'>
  ) }
);

right?

@n1ru4l I think you are the last one who worked on that area, thoughts? :)

Exactly @dotansimha, I of course should have added that to my issue report 馃槄 Thanks for figuring it out anyway!

@dotansimha Yes, should be pretty straight-forward to implement a failing test case (based on the information provided by @voxpelli) and adjust the implementation. I can take a look over the next few days!

@dotansimha Yes, should be pretty straight-forward to implement a failing test case (based on the information provided by @voxpelli) and adjust the implementation. I can take a look over the next few days!

Awesome, thank you so much :)

Fixed in @graphql-codegen/[email protected]. Thanks @voxpelli @n1ru4l !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NickClark picture NickClark  路  3Comments

bastman picture bastman  路  3Comments

edorivai picture edorivai  路  3Comments

zenVentzi picture zenVentzi  路  3Comments

leebenson picture leebenson  路  3Comments