zth/rescript-relay

Handling Interface with @refetchable directive

WooWan opened this issue · 2 comments

Hello, I appreciate your work, and I believe there's an opportunity to enhance the handling of interface.
Currently, when handling an interface, it generates a variant if there is only an inline fragment. However, it does not generate a variant when using the refetchable directive.

This issue is related to ##315

Without refetchable directive, it generates:

interface Book {
  title: String!
  author: Author!
}

type Textbook implements Book {
  title: String!
  author: Author!
  courses: [Course!]!
}

type ColoringBook implements Book {
  title: String!
  author: Author!
  colors: [String!]!
}

type Query {
  books: [Book!]!
}
module BookFragment = %relay(`
  fragment MyComponent_book on Book {
    ... on Textbook {
      title
      courses {
        name
      }
    }
    ... on ColoringBook {
      title
      colors
    }
  }
`)

...

let book = BookFragment.use(book)
// `book` would roughly be:
// type fragment = [
//   | TextBook({ title: string, courses: array<course> })
//   | ColoringBook({ title: string, colors: array<string> })
//   | UnselectedUnionMember(string)
// ]

However, with the refetchable directive, it generates:

module BookFragment = %relay(`
  fragment MyComponent_book on Book 
@refetchable(queryName: "Book_Fragment_RefetchQuery")
{
    ... on Textbook {
      title
      courses {
        name
      }
    }
    ... on ColoringBook {
      title
      colors
    }
  }
`)

let book = BookFragment.useRefetchable(book)
// `book` would roughly be:
// type fragment = {
//   title: string,
//   courses: option<array<course>>,
//   colors: option<array<string>>
// }

I'm not certain if this behavior is due to the way types are handled by Relay, I hope we can improve this aspect as well!

Confirmed this also happens when handling a union

zth commented

Hey! Yeah this is unfortunately something controlled by Relay, where we have little influence at the moment.