[relay-compiler] Unexpected type/__typename for fragments on interfaces
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
Hello,
I have a case here where the typescript types generated by the relay-compiler look wrong to me.
Let's say I've got the following schema
```graphql
interface TestInterface implements Node{
id: ID!
fieldA: String!
}
type TypeWithFieldB implements Node & TestInterface {
id: ID!
fieldA: String!
fieldB: String!
}
type TypeWithFieldC implements Node & TestInterface {
id: ID!
fieldA: String!
fieldC: String!
}
```
# Example 1 (which works like I would expect it)
If I now create a fragment like this
```tsx
useFragment(graphql`fragment Test on TestInterface {
... on TypeWithFieldB {
__typename
fieldA
fieldB
}
... on TypeWithFieldC {
__typename
fieldA
fieldC
}
}`, null)
```
Then the generated types look good
```ts
export type Test$data = {
readonly __typename: "TypeWithFieldB";
readonly fieldA: string;
readonly fieldB: string;
readonly " $fragmentType": "Test";
} | {
readonly __typename: "TypeWithFieldC";
readonly fieldA: string;
readonly fieldC: string;
readonly " $fragmentType": "Test";
}
```
# Example 2 (Wrong __typename)
If I create a fragment like this (fieldA pulled to the top):
```tsx
useFragment(graphql`fragment Test2 on TestInterface {
fieldA
... on TypeWithFieldB {
__typename
fieldB
}
... on TypeWithFieldC {
__typename
fieldC
}
}`, null)
```
Then the generated types look like this:
```
export type Test2$data = {
readonly __typename: "TypeWithFieldB";
readonly fieldA: string;
readonly fieldB?: string;
readonly fieldC?: string;
readonly " $fragmentType": "Test2";
};
```
While the type itself looks like a sensible merge of TypeWithFieldB and TypeWithFieldC the __typename should probably not be "TypeWithFieldB".
# Example 3 (Wrong __typename caused by refetchable fragment)
```tsx
useRefetchableFragment(graphql`fragment Test3 on TestInterface @refetchable(queryName: "Test3RefetchQuery") {
... on TypeWithFieldB {
__typename
fieldA
fieldB
}
... on TypeWithFieldC {
__typename
fieldA
fieldC
}
}`, null)
```
Then the generated types look like in Example 2.
What is surprising to me here is that the fragment structure is chosen exactly as in the working example 1 with the only difference that here the fragment is marked as refetchable.
---
Repo with example code: https://github.com/joeried/relay-compiler-issue-repro/
If I'm not mistaken, then the generated types are just wrong, or am I mistaken? Is there a way to get types that are structured more like the ones in Example 1?
Contributor guide
Assessment
This issue has not been assessed yet.