Graphql-code-generator: Mappers are not used for interface types

Created on 6 Aug 2020  Â·  3Comments  Â·  Source: dotansimha/graphql-code-generator

Describe the bug
I have been migrating my code from [email protected] to [email protected], and have noticed that v1.9.1 applies mappers to interfaces (which is behavior that I would expect), while 1.17.7 does not — instead, it expands types implementing interface, and it breaks my types.

I expect ResolversParentTypes['User'] to be User: UserParent in accordance to mapper config (where it's set as User: ./parents#UserParent), but v1.13.1 and later versions output User: ResolversParentTypes['Human'] | ResolversParentTypes['Bot'] instead.

I have tracked down the breaking change to happen between v1.13.0 and v1.13.1, in this particular commit — https://github.com/dotansimha/graphql-code-generator/commit/cbd87933dd79685935b8bb1db724340a1166dc4e#diff-9ecae63f92a8c9dcfce805bfbe64220aR426-R442 — it puts graphql.isInterfaceType check before isMapped check, so it never happens for interface types.

To Reproduce
Steps to reproduce the behavior:

  1. Follow the link: https://codesandbox.io/s/compassionate-hooks-whqs9?file=/types.ts:3877-3946
  2. Run yarn && yarn generate from terminal;
  3. Observe types.ts, line 122, you will see it's User: ResolversParentTypes['Human'] | ResolversParentTypes['Bot'], which is incorrect result, because mapper isn't honored;
  4. In package.json, roll version back to "@graphql-codegen/typescript-resolvers": "1.13.0";
  5. Run yarn && yarn generate from terminal again;
  6. Observe types.ts, line 122, you will see it's User: UserParent, which is desired result;

Sample config I use for case reproduction:

  1. My GraphQL schema:
type Query {
    user(id: ID!): User!
}

interface User {
    id: ID!
    username: String!
}

type Human implements User {
    id: ID!
    username: String!
    email: String!
}

type Bot implements User {
    id: ID!
    username: String!
    token: String!
}
  1. My GraphQL operations:
query user {
    user(id: 1) {
        id
    }
}
  1. My codegen.yml config file:
schema: schema.graphql
documents: document.graphql
generates:
  types.ts:
    plugins:
      - typescript
      - typescript-resolvers
    config:
      mappers:
        User: ./parents#UserParent

Expected behavior
If some type is specified in mappers, it should be always mapped, regardless if it's an interface.

Environment:

  • OS: any
  • @graphql-codegen/add: 1.17.7
  • @graphql-codegen/cli: 1.17.7
  • @graphql-codegen/typescript: 1.17.7
  • @graphql-codegen/typescript-resolvers: 1.13.1
  • graphql: ^15.0
  • NodeJS: v10.21.0

Additional context
In case this behavior was intended, I've implemented a PR https://github.com/dotansimha/graphql-code-generator/pull/4531 that provides a configuration option for selecting between current and pre-1.13.1 behavior.

UPD: discarded configuration option, reverted behavior to pre-1.13.1 by default.

bug plugins waiting-for-release

Most helpful comment

Fixed in @graphql-codegen/[email protected].

All 3 comments

A bit relevant to this issue. Is there any way to apply interface's base mapper to child types?
E.g. if i have

mappers:
        User: ./parents#UserParent

then for both User, Bot, Human the UserParent type will be used until another one is explicitly specified. Not sure if it makes sense for anyone except me though 😅 wdyt?

There is no way to automatically expand interfaces from what I have seen in the source. However, you can create a separate issue and submit your own PR if you consider this feature to be useful, it doesn't seem hard to implement.

Fixed in @graphql-codegen/[email protected].

Was this page helpful?
0 / 5 - 0 ratings