graphql-code-generator icon indicating copy to clipboard operation
graphql-code-generator copied to clipboard

[Mappers] Mapper Not Used for Nested Types

Open nathanforce opened this issue 6 years ago • 3 comments

Describe the bug

When using a defaultMapper, nested types are not mapped to their ResolverType. I've provided a CodeSandbox. I've added a field, friends, to User. friends is of type UserFriendsConnection.

I'd expect that the defaultMapper, in this case Required<{T}>, be applied to the nested User types of UserFriendsEdge.node and UserFriendsConnection.nodes.

export type UserFriendsConnection = {
   __typename?: 'UserFriendsConnection',
  edges: Array<UserFriendsEdge>,
  nodes: Array<User>,
  totalCount: Scalars['Int'],
};

export type UserFriendsEdge = {
   __typename?: 'UserFriendsEdge',
  cursor: Scalars['String'],
  node: User,
};

To Reproduce Steps to reproduce the behavior:

https://codesandbox.io/s/graphql-codegen-issue-template-o0y03

nathanforce avatar Dec 17 '19 05:12 nathanforce

I can still reproduce it with 1.15.0. Was it forgotten?

Edit: How does the generation of combined plugins work? Is their content just merged or can they affect each other? From some observation, it seems like they are just merged and you get those base types generated by the base typescript plugin that has no access to mappers.

If this would be somehow achieved then we would not need the mapperTypeSuffix as there would be no clashes with the original type.

radoslavkarlik avatar May 29 '20 14:05 radoslavkarlik

Those types are generated from your GraphQL Schema, they are not generated to be used as parent types so this is an intentional behavior because those types are used in operations package as well. In this case, you need to provide custom types for UserFriendsConnection and UserFriendsEdge as well.

@RadoslavK For each output file, results of plugins are concatenated so they can affect each other. As you already said base typescript plugin is not affected by mappers because mappers belongs to resolvers plugin.

generates:
   a-file.ts:
      - typescript
      - typescript-operations
   b-file.ts:
      - typescript
      - typescript-resolvers

We can discuss about typescript plugin's behavior with mappers. I'm marking this issue as enhancement instead of bug. @dotansimha What do you think?

ardatan avatar May 29 '20 23:05 ardatan

Those types are generated from your GraphQL Schema, they are not generated to be used as parent types so this is an intentional behavior because those types are used in operations package as well. In this case, you need to provide custom types for UserFriendsConnection and UserFriendsEdge as well.

@radoslavk For each output file, results of plugins are concatenated so they can affect each other. As you already said base typescript plugin is not affected by mappers because mappers belongs to resolvers plugin.

generates:
   a-file.ts:
      - typescript
      - typescript-operations
   b-file.ts:
      - typescript
      - typescript-resolvers

We can discuss about typescript plugin's behavior with mappers. I'm marking this issue as enhancement instead of bug. @dotansimha What do you think?

Hi, I didn't understand this explanation, but does this issue also apply to mappers for specific types when they are nested--as opposed to a default mapper? That's the problem I'm facing; I have a parent and a child, and I want to map the child to a particular type, but the child doesn't get mapped. Mapping the parent or mapping that child type when it's a top-level type works as expected.

EDIT: And in case it matters, the use case is:

  • Making a grandchild a required field of the child.
  • But resolving that required grandchild in a separate resolver from the child, by using a resolver chain.
  • Which requires letting the child's resolver return a type where the grandchild is not required.
  • Which I'm trying to do by mapping the child type to a custom type that omits the grandchild.

csimmons0 avatar Sep 26 '24 13:09 csimmons0