Select 嵌套属性上带有 useResult 的 graphql 数据

Select graphql data with useResult on nested properties

我们有一个像这样执行的 graphql 查询:

// rosterDispatchGroup.query.graphql
query rosterDispatchGroup($fromDate: DateTime!) {
  rosterDispatchGroup(fromDate: $fromDate) {
    ... on ApiError {
      message
    }
    ... on RosterDispatchGroupArray {
      data {
        date
        dispatchGroup
      }
    }
  }
}

和returns数据array(或ApiError的消息):

{
  "data": {
    "rosterDispatchGroup": {
      "data": [
        {
          "date": "2020-10-28",
          "dispatchGroup": [ "A" ]
        }
    ]
}

要在 Vue 模板中使用这些数据,我们这样做:

import { useResult } from '@vue/apollo-composable'
import { defineComponent } from '@vue/composition-api'
import { useRosterDispatchGroupQuery } from 'src/graphql/generated/operations'

export default defineComponent({
  setup() {
    const { result, loading, error } = useRosterDispatchGroupQuery(
      () => { return { fromDate: new Date() } },
    )

    const dispatchGroups = useResult( result, [],
      (data) => data.rosterDispatchGroup.data // property data does not exist on type
    )
    return { dispatchGroups, loading, error }
  },
})

此代码工作正常,但我们收到以下打字稿错误消息:

roperty 'data' does not exist on type '({ __typename?: "RosterDispatchGroupArray" | undefined; } & { data?: ({ __typename?: "RosterDispatchGroup" | undefined; } & Pick<RosterDispatchGroup, "date" | "dispatchGroup">)[] | null | undefined; }) | ({ ...; } & Pick<...>)'.
Property 'data' does not exist on type '{ __typename?: "ApiError" | undefined; } & Pick<ApiError, "message">'.Vetur(2339)

正确的方法是什么nitpick the result with useResult and avoid a typescript error? We used graphql-codegen to generated the required typescript code and we used this tutorial求灵感

想通了。我们只需要在返回对象数据 'array':

之前检查 __typename 属性
export default defineComponent({
  setup() {
    const dispatchGroups = useResult(result, [], (data) => {
      if (data.rosterDispatchGroup.__typename === 'RosterDispatchGroupArray') {
        return data.rosterDispatchGroup.data
      }
    })

    const apiError = useResult(result, null, (data) => {
      if (data.rosterDispatchGroup.__typename === 'ApiError') {
        return data.rosterDispatchGroup
      }
    })