如何实现isTypeOf方法? [英] How to implement isTypeOf method?

查看:239
本文介绍了如何实现isTypeOf方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下模式:

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
    }
  }
}

然后我得到下面的回报:

Then I get the return below:

{
  "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函数,但仍收到错误消息.

As you can see, I've implemented the isTypeOf function but I am still getting the error message.

我在做什么错了?

注意:

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

推荐答案

isTypeOf是一个以编程方式创建架构时传递给GraphQLObjectType构造函数的函数. resolveType函数和联合/接口的同上.如果使用SDL并使用buildSchema创建架构,则无法将这些函数注入到创建的架构中,就像您无法为Query.

isTypeOf is a function that is passed to the constructor of a GraphQLObjectType when you create your schema programatically. Ditto for resolveType functions and unions/interfaces. If you use SDL and create your schema using buildSchema, there is no way to inject those functions into your created schema, just like you don't have a way to provide resolvers for fields on types other than Query and Mutation.

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

You have a couple of options. One option is to utilize the default resolveType behavior. This checks for a __typename property on the object, and falls back to calling isTypeOf on every implementing type until it matches. That means if you're using a class, it should be sufficient to do something like this:

export default class Todo {
  get __typename() {
    return 'Todo'
  }
}

更好的选择是删除buildSchema并使用graphql-tools中的makeExecutableSchema.然后,您可以直接在解析器中定义resolveType和/或isTypeOf函数.例如:

The better option would be to drop buildSchema and use makeExecutableSchema from graphql-tools. Then you can define your resolveType and/or isTypeOf functions directly in your resolvers. For example:

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'
    },
  }
}

您不仅可以通过这种方式轻松定义isTypeOfresolveType,还可以轻松地为任何类型的字段添加解析器,并轻松添加自定义标量.如果仅使用buildSchema,则无法(轻松地)执行任何操作.

Not only can you easily define isTypeOf or resolveType this way, you can also easily add resolvers for fields of any type and add custom scalars without any hassle. You cannot do any of that (easily) if you're using just buildSchema.

如果您更喜欢使用isTypeOf而不是resolveType,则解析程序将如下所示:

If you prefer to utilize isTypeOf instead of resolveType, the resolvers would look something like this:

const resolvers = {
  Query: {
    node: (obj, args, context, info) => {
      return new Todo('1', 'Todo 1')
    }
  },
  Todo: {
    __isTypeOf: (obj, context, info) => {
      return obj instanceof Todo
    },
  }
}

只有一个或另一个是必要的.为您使用的每种抽象类型编写resolveType函数,或者为每种可能是抽象类型的对象类型编写isTypeOf.

Only one or the other is necessary. Either write a resolveType function for every abstract type you use, or write a isTypeOf for every object type that could be an abstract type.

这篇关于如何实现isTypeOf方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆