Skip to content

@raw_response_type mocking: conditional fragments from @skip/@include not properly enforced in types #5057

@jantimon

Description

@jantimon

This is a follow-up to #4949 which is currently being worked on by @vhfmag to address the broken type generation bug of @raw_response_type and @skip/@include.

Also this issue is independent from the type generation issues with @semanticNonNull #4915

This issue specifically focuses on the case where @raw_response_type and the @skip/@include directives are used for mocking

When using @include/@skip directives with @raw_response_type the generated types don't enforce conditional field data to be part of the mock data. Causing mock data going out of sync and creating inconsistencies between mock structure and actual server responses

Consider this query with a conditional fragment:

const actorQuery = graphql`
  query ActorDemoQuery($includeContact: Boolean!) @raw_response_type {
    viewer {
      actor {
        id
        name
        ...ContactDetails @include(if: $includeContact)
      }
    }
  }
`;

const contactDetailsFragment = graphql`
  fragment ContactDetails on Actor {
    email
    phone
  }
`;

Current raw response types allow creating mock data without enforcing conditional fields:

const mockActorQuery = (includeContact: boolean) =>
  createMockedQuery<ActorDemoQuery>(
    actorQuery,
    {
      viewer: {
        actor: {
          id: "actor-123",
          name: "John Doe",
          // Types pass although email/phone missing when includeContact=true
          // This creates inconsistency with actual server response
        },
      },
    },
    { includeContact },
  );

export const ActorWithContactDemo = () => {
   // create a mock with args set to includeContact=true but no contact fields
  const queryRef = useMockedQuery(mockActorQuery(true));
  return <Actor actor={queryRef.actor} />;
};

When $includeContact is true, the actual GraphQL response would include email and phone fields, but the types don't enforce it for the mock data. This creates a mismatch between test data and production behavior

Maybe we could add an argument for @raw_response_type to enforce complete input types that matches a full server response and prevents incomplete mock data:

  • @raw_response_type(kind: "INPUT") - Enforces complete input types matching full server response
  • @raw_response_type(kind: "OUTPUT") (default) - Current behavior for optimistic updates

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions