relay icon indicating copy to clipboard operation
relay copied to clipboard

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

Open vhfmag opened this issue 10 months ago • 1 comments

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;
};

vhfmag avatar Feb 19 '25 20:02 vhfmag

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 avatar Feb 20 '25 14:02 vhfmag

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

vhfmag avatar Mar 28 '25 18:03 vhfmag

Thanks for the ping. Let me follow up.

captbaritone avatar Mar 28 '25 18:03 captbaritone

Repro unit test here https://github.com/facebook/relay/pull/4940 to get us started.

captbaritone avatar Mar 28 '25 18:03 captbaritone

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 avatar Mar 28 '25 23:03 captbaritone

My apologies, I didn't see https://github.com/facebook/relay/pull/4915 linked here. @evanyeung will followup on the PR.

captbaritone avatar Mar 31 '25 18:03 captbaritone

thanks for the follow up!

vhfmag avatar Mar 31 '25 22:03 vhfmag

@captbaritone @evanyeung given the PR merge was reverted, can we reopen this issue?

vhfmag avatar Oct 23 '25 20:10 vhfmag