eddeee888 / graphql-code-generator-plugins

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

[BUG] mappers for interface types on payload objects aren't generated correctly #266

Closed joeyhotz closed 6 months ago

joeyhotz commented 6 months ago

Describe the bug When you have an interface type on a response payload object for a mutation, and you have a mapper for the implemented types, the types aren't generated correctly.

I have a repo here to reproduce the issue: https://github.com/joeyhotz/example-interface-type-bug-payload

To Reproduce Steps to reproduce the behavior: _1. yarn _2. Go to src/schema/Mutation/createUser.ts

Expected behavior The types generated for the mutation response should allow { user: { id: "123" } } as a response for the mutation as I've defined the mappers as:

export type AdminUserMapper = { id: string };
export type CustomerUserMapper = { id: string };

It works fine for the user query.

Additional context Happy to provide more context if this is not enough info. Hopefully the reproducible repo is good enough 🙏 Thank you so much for taking a look, I'm loving the codegen plugin and really hope to see this fixed as it's blocking some nice code structures.

nikhilgupta345 commented 6 months ago

Running into this as well, would love to see a fix!

eddeee888 commented 6 months ago

Thank you! The reproducible repo is great!

I'll take a deeper look soon 👀

eddeee888 commented 6 months ago

Hello 👋

I'm doing a fix upstream in @graphql-codege/typescript-resolvers: https://github.com/dotansimha/graphql-code-generator/pull/9962.

With your posted repo, could you do the following and test:

So basically:

$ yarn remove @graphql-codegen/typescript @graphql-codegen/typescript-resolvers @eddeee888/gcg-typescript-resolver-files
$ yarn add -ED @eddeee888/gcg-typescript-resolver-files@pr269-run477-1

Then run yarn generate.

We are expecting this main change in types.generated.ts:

export type ResolversTypes = {
  // ... other fields
- CreateUserPayload: ResolverTypeWrapper<CreateUserPayload>;
+ CreateUserPayload: ResolverTypeWrapper<Omit<CreateUserPayload, 'user'> & { user?: Maybe<ResolversTypes['User']> }>;};
}

Now, the mappers should work. Please let me know if this fixes your issue. Thank you!

joeyhotz commented 6 months ago

yayyy thanks for that explanation on how to run, can confirm it works in the example repo :D thanks for fixing this :D :D

nikhilgupta345 commented 6 months ago

@eddeee888 Thanks for the fix above! I created another repo here for a related bug where the mapper for the interface type itself isn't being set properly as the Resolver return type.

The way I was anticipating it would work is that (based on the example in the linked repo):

  1. The user query returns a User interface type. It should expect the return value of the UserMapper
  2. The __resolveType on User.ts should have the UserMapper as the parent type, and can be used to dictate which of the implementing types is being returned
  3. The parent for AdminUser type resolver functions should be the AdminMapper (and similar for CustomerMapper). If they are not defined then it should default to UserMapper as the parent type.

Please let me know if I'm thinking about this the wrong way! The reason I would like these types is that I have a base table in my DB that maps cleanly to the interface type, but we need to fetch additional data to resolve fields on the actual object type.

nikhilgupta345 commented 6 months ago

I also noticed that if you have a type resolver for an interface, it doesn't get included in the generated resolvers.generated.ts file

eddeee888 commented 6 months ago

Hi @nikhilgupta345 ,

I believe your understanding is correct. Let me create another issue to track your problem:

https://github.com/eddeee888/graphql-code-generator-plugins/issues/278

eddeee888 commented 6 months ago

For the issue originally reported, it's been fixed in: