Skip to content

relay-compiler generates invalid Typescript for @raw_response_type + combination of conditional and non-conditional fragments #4914

@vhfmag

Description

@vhfmag
Contributor

Given the code below:

export const query = graphql`
    query AppQuery($showEmail: Boolean!) @raw_response_type {
        ...AppFragment
        ...AppConditionalFragment
    }
`;

export const fragment = graphql`
    fragment AppFragment on Query {
        account {
            name
        }
    }
`;

export const conditionalFragment = graphql`
    fragment AppConditionalFragment on Query {
        account @include(if: $showEmail) {
            email
        }
    }
`;

Relay compiler generates the following types (notice the account field is listed twice):

export type AppQuery$rawResponse = {
  readonly account: {
    readonly id: string;
    readonly name: string;
  } | null | undefined;
  readonly account: {
    readonly email: string;
  } | null | undefined;
};

Which typescript interprets by using the first declaration of a given field and ignoring all others, leading to errors like:

Image

This very reproduction can be found at https://github.com/vhfmag/relay-ts-typegen-issue-repro

Instead, relay compiler should generate something like:

export type AppQuery$rawResponse = {
  readonly account: {
    readonly id: string;
    readonly name: string;
    readonly email?: string | null | undefined;
  } | null | undefined;
};

Activity

vhfmag

vhfmag commented on Feb 20, 2025

@vhfmag
ContributorAuthor

Flow has the same issue, only in the opposite direction (it uses the last declaration instead of the first). E.g. (playground link)

export type AppQuery$rawResponse = {|
  +me: ?{|
    +firstName: ?string,
    +id: string,
  |},
  +me?: ?{|
    +lastName: ?string,
  |},
|};

function fn(val: AppQuery$rawResponse) {
  val.me.id; // Cannot get `val.me.id` because property `id` is missing in object type [1]. [prop-missing]
}
vhfmag

vhfmag commented on Mar 28, 2025

@vhfmag
ContributorAuthor

@captbaritone sorry for the direct ping, but I thought this qualified as "falling through the cracks" from your Discord message 😅

captbaritone

captbaritone commented on Mar 28, 2025

@captbaritone
Contributor

Thanks for the ping. Let me follow up.

captbaritone

captbaritone commented on Mar 28, 2025

@captbaritone
Contributor

Repro unit test here #4940 to get us started.

captbaritone

captbaritone commented on Mar 28, 2025

@captbaritone
Contributor

I can see this is somehow related to us not doing selections_to_map as we do for linked field selections for all raw response selection sets. However blindly adding it results in some other unexpected changes so more investigation is required. If anyone wants to try to track down what needs to be added/changes here let me know.

captbaritone

captbaritone commented on Mar 31, 2025

@captbaritone
Contributor

My apologies, I didn't see #4915 linked here. @evanyeung will followup on the PR.

vhfmag

vhfmag commented on Mar 31, 2025

@vhfmag
ContributorAuthor

thanks for the follow up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @captbaritone@vhfmag@facebook-github-bot

      Issue actions

        `relay-compiler` generates invalid Typescript for `@raw_response_type` + combination of conditional and non-conditional fragments · Issue #4914 · facebook/relay