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

[typescript-operations] operation type not restricted to inline fragment

Open OscarBarrett opened this issue 4 years ago • 8 comments
trafficstars

Describe the bug typescript-operations does not appear to take into account the specific inline fragments used, instead generating a type that could include anything from the returned interface.

To Reproduce Have two or more types that share an interface.

Define a query that returns the interface, but only include one of the types in an inline fragment.

Codesandbox: https://codesandbox.io/s/long-http-1wibc

  1. My GraphQL schema:
type Query {
    entries(type: [String]): EntryInterface
}

interface EntryInterface {
    title: String
}

type first_Entry implements EntryInterface {
    title: String
    first: String
}

type second_Entry implements EntryInterface {
    title: String
    second: String
}
  1. My GraphQL operations:
query first {
    entries(type: "first") {
        ...on first_Entry {
            __typename
            title
            first
        }
    }
}

  1. My codegen.yml config file:
schema: schema.graphql
documents: document.graphql
generates:
  types.ts:
    plugins:
      - typescript
      - typescript-operations

Expected behavior

FirstQuery is generated as follows:

export type FirstQuery = {
  __typename ? : 'Query',
  entries ? : {
    __typename: 'first_Entry',
    title ? : string | null | undefined,
    first ? : string | null | undefined
  } | {
    __typename ? : 'second_Entry'
  } | null | undefined
};

The expected type would be:

export type FirstQuery = {
  __typename ? : 'Query',
  entries ? : {
    __typename: 'first_Entry',
    title ? : string | null | undefined,
    first ? : string | null | undefined
  } | null | undefined
};

(i.e. no { __typename?: 'second_Entry' } in the union).

Environment:

  • OS: MacOS
  • @graphql-codegen/typescript: 2.2.4
  • @graphql-codegen/typescript-operations: 2.1.8
  • NodeJS: 14

Additional context In typescript-operations v1, when using skipTypename: true objects only containing __typename? would be removed, so this could be avoided. In v2 the union will include {} instead.

OscarBarrett avatar Oct 20 '21 16:10 OscarBarrett

Hitting this same issue, which is preventing us from updating. We'd have to make type assertions to force the correct type which is not ideal.

gbettencourt avatar Nov 10 '21 00:11 gbettencourt

I'm running into the same problem. This is also preventing an upgrade to graphql 16 in our codebase. This problem is especially annoying when using skipTypename:true, as there are no fields that can help us narrow the resulting type of a query.

peternedap avatar Apr 08 '22 10:04 peternedap

Looks like this is still a thing for me. Makes inline fragments pretty challenging to work with type-wise, as I have to do tons of type name conditionals just to read a field which should be marked as optional.

nandorojo avatar Mar 15 '23 20:03 nandorojo

+1

nelsonchen5 avatar Jun 30 '23 22:06 nelsonchen5

Running into this issue as well

erickreutz avatar Dec 11 '23 02:12 erickreutz

Same here

ktaletski avatar Apr 15 '24 09:04 ktaletski