houdini icon indicating copy to clipboard operation
houdini copied to clipboard

Fragment conflict with TypeScript

Open ChrisPlease opened this issue 2 years ago • 1 comments

Describe the bug

I have a component with a colocated fragment. I'm trying to use the id field of the fragment for a second query inside the component, but I'm running up against a TypeScript error:

fragment FooPartial on Foo {
  id
  name
}

In the same component, I'd like to use the id from the partial as a variable in a second query:

query BarQuery($fooId: ID) @load {
  barList(fooId: $fooId) {
    ...BarList
  }
}

I set up the load function according to the docs, but here's where my problem is:

  export const _BarQueryVariables: BarQueryVariables = ({ props }) => {
    return { fooId: props.foo.id || '' }
  }

TS doesn't recognize id

Property id does not exist on FooPartial

The problem is, this query works, but TS doesn't think it does.

TS expects props.foo.shape.id because of the fragment, but when I use this, id is undefined.

See thread: https://discord.com/channels/1024421016405016718/1092662156002082836/1092662156002082836

Severity

annoyance

Steps to Reproduce the Bug

n/a

Reproduction

No response

ChrisPlease avatar Apr 04 '23 23:04 ChrisPlease

I can add a potentially related bug. I am loading two fragments as part of a query:

const query = graphql(`
	query Viewer {
		viewer {
			user {
				...UserInfo
			}
			memberships {
				...MembershipInfo
			}
		}
	}
`);

The MembershipInfo returns the correct type with all GraphQL properties:

const memberships: {
    readonly role: string;
    readonly organization: {
        readonly id: string;
        readonly name: string;
        readonly slug: string;
    };
    readonly $fragments: {
        MembershipInfo: true;
    };
}[]

However, the user fragment only returns the $fragments property. It should include an ID, name and email.

const user: {
    readonly $fragments: {
        UserInfo: true;
    };
}

The only difference I can see between the two is that memberships is a fragment on an array relationship, while the user fragment is just one object type queried on another object type.

When I console.log the user fragment it contains all the correct values, but the type does not match.

jhlabs avatar Apr 05 '23 08:04 jhlabs

Sorry it took me a bit to get to you @ChrisPlease. Are you still running into issues? If so, can you show me the definition of BarQueryVariables that's generated? I'm going to close this issue but Im more than happy to re-open if the problem persists.

@jhlabs I think you are running into a separate problem known as fragment masking. If you search here or on discord for that term you should be able to find an explanation

AlecAivazis avatar Jul 07 '24 08:07 AlecAivazis