首页 > 解决方案 > __resolveType 返回空对象

问题描述

我正在尝试使用 graphql 实现表单验证。出于某种原因,当我运行此查询时:

mutation validateForm($input: ValidateFormInput!) {
    test: validateForm(
       input: $input
    ) {
        id
        fieldValidations {
            ... on FailedValidation {
                id
            }
        }
    }
  }

并且有一个字段验证没有错误('SuccessfullValidation')它返回 {id:'some-id',fieldValidations:[{}]} 当它应该返回 {id:'some-id',fieldValidations:[] }。这对我来说尤其没有任何意义,因为 ID 在两个字段中都被标记为不可为空的字段,但是我没有收到任何错误。

解析器

FieldValidation: {
    __resolveType(obj: any) {
        if (obj.error || (obj._doc && obj._doc.error)) {
            return 'FailedValidation';
        }
        return 'SuccessfullValidation';
    },
}

类型定义

type SuccessfullValidation {
    id: ID!

    filter: Filter!
    field: Field!
}

type TestError {
    hint: String!
    details: String!
}

type FailedValidation {
    id: ID!

    filter: Filter!
    field: Field!
    error: TestError
}

union FieldValidation = SuccessfullValidation | FailedValidation

extend type Query {
    getFieldValidations: [FieldValidation!]!
}

type FormValidation {
    id: ID!
    fieldValidations: [FieldValidation!]!
}

input ValidateFormInputFields {
    id: String!
    value: String! 
}

input ValidateFormInput {
    fields: [ValidateFormInputFields!]!
    userId: Int!
}


extend type Mutation {
    validateForm(input: ValidateFormInput!): FormValidation!
}

标签: graphqlapollo

解决方案


这是预期的行为。从规格

片段可以在选择集中内联定义。这样做是为了根据运行时类型有条件地包含字段。

类型条件(即on FailedValidation)只是一种根据运行时类型过滤解析哪些字段的方法。它们不是过滤实际结果列表的一种方式——GraphQL 中没有内置过滤。

如果要过滤FieldValidations 返回的列表,则fieldValidations需要向该字段添加某种参数,然后实现适当的解析器逻辑。

顺便说一句,您不会看到非空字段为空的验证错误,除非该字段被实际请求并且它解析为空。在这种情况下,内联片段上的类型条件实际上导致了一个空的选择集——从 GraphQL 的角度来看,该id字段没有被请求,因此它不会对其进行空检查。


推荐阅读