babyfish-ct / graphql-ts-client

Typescript DSL for GraphQL.
MIT License
147 stars 20 forks source link

Error union types does not has id field #27

Open robsonfj opened 1 year ago

robsonfj commented 1 year ago

Getting error when trying to generate types when the schema has union

Error: Section does not has id field \node_modules\graphql-ts-client-codegen\dist\state\GraphQLStateFetcherWriter.js:63:35 throw new Error(${nodeType.name} does not has id field);

Schema

type Document {
    id: ID!
    sections: [Section!]!
  }

union Section = SectionTitle | SectionParagraph| SectionDivider

type BaseEntity {
    id: ID!
  }

type SectionDivider implements BaseEntity {
    id: ID!
  }

  type SectionTitle implements BaseEntity {
    id: ID!
    text: String
  }
  type SectionParagraph implements BaseEntity {
    id: ID!
    text: String
  }
babyfish-ct commented 1 year ago

image

I copied your schema and pasted it into local file, use loadLocalSchema("scripts/local.graphql") to generate code

Cannot reproduce, it works

robsonfj commented 1 year ago

hmm, i'm using the GraphQLStateGenerator... could that be the diference? running here with AsyncGenerator works too... only with GraphQLStateGenerator that fails


const generator = new GraphQLStateGenerator({
    schemaLoader: async () => {
      const { typedefs } = await import('../server/src/graphql/schemas')
      const schema = buildASTSchema(typedefs)
      return schema
    },

    targetDir: path.join(typesPath, 'graphql'),
  })

  await generator.generate()
babyfish-ct commented 1 year ago

Yes, they are very different

  1. AsyncGenerator: Basic uages
  2. ApolloGenerator: Work with apollo client
  3. RelayGenerator: Work with relay
  4. GraphQLStateGernator: Work with my another framework: graphql-state

After discovering the shortcomings of apollo client and facebook relay, I developed graphql-state. Graphql-state is actually a relational database in the browser, so it needs all object have ids. However, until now, graphql-state does not support the use of union types to express the inheritance relationship of objects with ids.

If you don't want to use graphql-state, no issue; if you want to use graphql-state, here's a work around (because I'm currently busy developing another project of mine: jimmer, I can't find time to implement this not simple function enhancement in the short term)

type Document {
    id: ID!
    sections: [Section!]!
}

interface Section {
    id: ID!
}

type SectionDivider implements Section {
    id: ID!
}

type SectionTitle implements Section {
    id: ID!
    text: String
}
type SectionParagraph implements Section {
    id: ID!
    text: String
}
robsonfj commented 1 year ago

Ah.. ok i'll use this workaround.... thanks 👍😁