Skip to content

Interface confusion #338

@kevinSuttle

Description

@kevinSuttle

carried over from graphql/graphql-relay-js#25 (comment)

x.resolveType field type must be Output Type but got: undefined.
Error: X may only implement Interface types, it cannot implement: undefined.

I've run into one of these or a circular dependency a number of times following the docs and examples in the wild.

It seems developers always end up needing to implement a type registry, which I thought a Schema was.

https://facebook.github.io/graphql/#sec-Interface-type-validation The docs here are almost empty, but even the one caveat makes very little sense. The section above it doesn't even mention isTypeOf, valueOf, or resolveType. I've found these on GitHub or StackOverflow.

Using the _schema introspection, Interfaces themselves don't appear as types (at least in my experience), which seems confusing, as does the following result:

   {
          "name": "__Type",
          "interfaces": []
        },
        {
          "name": "Boolean",
          "interfaces": null
        },

Another example: An app I'm working on will behave very differently depending on if I wrap a single Interface type with Array brackets as well.

interfaces: graphicType vs interfaces: [graphicType]
If do the latter, I get Error: Box may only implement Interface types, it cannot implement: undefined.

If I do the former, all the types that implement that interface return null, and get this in GraphiQL:

"errors": [
    {
      "message": "Expecting a function in instanceof check, but got [object Object]"
    }
  ]

Another confusing part of the spec is that interfaces are just fields. e.g. neither of the following work.
const boxType = new GraphicType({
const boxType = graphicType({

Babel throws an error.

var boxType = (0, _graphic2.default)({
                                     ^

TypeError: (0 , _graphic2.default) is not a function

Instead, you need to make it a predefined type.

const boxType = new GraphQLObjectType({
...
// which you then have to return as the implemented type
isTypeOf: (value) => value instanceof boxType,

Can you see how confusing that is, especially coming from an OOP perspective?

One suggestion from reactiflux discord was to put the Interface and its implementing types into one file, but that smells funny to me.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions