如何实现isTypeOf方法?

时间:2018-10-31 07:46:20

标签: node.js typescript express graphql express-graphql

给出以下模式:

interface INode {
  id: ID
}

type Todo implements INode {
  id: ID
  title: String!
}

type Query {
  node(id: ID!): INode
}

提供此类:

export default class Todo {
  constructor (public id: string, public title: string) { }

  isTypeOf(value: any): Boolean {
    return value instanceof Todo;
  }
}

给出此解析器:

type NodeArgs = {
  id: string
}
export const resolver = {
  node: ({ id }: NodeArgs) => {
    return new Todo('1', 'Todo 1');
  }
}

当我致电查询时:

query {
  node(id: "1") {
    id
    ... on Todo {
      title
    }
  }
}

然后我得到下面的回报:

{
  "errors": [
    {
      "message": "Abstract type INode must resolve to an Object type at runtime for field Query.node with value { id: \"1\", title: \"Todo 1\" }, received \"undefined\". Either the INode type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "node"
      ]
    }
  ],
  "data": {
    "node": null
  }
}

如您所见,我已经实现了isTypeOf函数,但仍然收到错误消息。

我在做什么错了?

注意:

  • 我正在使用Typescript,express和express-graphql;

1 个答案:

答案 0 :(得分:4)

isTypeOf是一个函数,当您以编程方式创建架构时,该函数将传递给GraphQLObjectType的构造函数。 resolveType函数和联合/接口的同上。如果您使用SDL并使用buildSchema创建架构,则无法将这些函数注入到您创建的架构中,就像您无法为{{1}以外的类型的字段提供解析器一样}和Query

您有两种选择。一种选择是利用默认的Mutation行为。这将检查对象上的resolveType属性,并退回到对每种实现类型调用__typename直到匹配。这意味着,如果您使用的是类,那么要做这样的事情就足够了:

isTypeOf

更好的选择是删除export default class Todo { get __typename() { return 'Todo' } } 中的buildSchema并使用makeExecutableSchema。然后,您可以直接在解析器中定义graphql-tools和/或resolveType函数。例如:

isTypeOf

不仅可以通过这种方式轻松定义const resolvers = { Query: { node: (obj, args, context, info) => { return new Todo('1', 'Todo 1') } }, INode: { __resolveType: (obj, context, info) => { if (obj instanceof Todo) return 'Todo' }, } } isTypeOf,还可以轻松地为任何类型的字段添加解析器,并轻松添加自定义标量。如果仅使用resolveType,则无法(轻松地)执行任何操作。