You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ApolloServer.executeOperation() TypeScript类型报错问题求助

解决Apollo Server executeOperation返回TypeScript联合类型报错问题

使用apolloServer.executeOperation测试GraphQL子图时,实际返回single类型响应,但TypeScript仍将response.body视为包含incremental的联合类型,导致访问singleResult时报错。

测试代码

it('should fetch a user', async () => {
  const query = gql`
    query Query {
      user {
        id
        email
      }
    }
  `
  const response = await apolloServer.executeOperation<User>({
    query,
  })
  const util = require('util')
  console.log('response.body', util.inspect(response.body, { depth: null }))
  expect(response.body.kind).toEqual('single')
  expect(response.body.singleResult.data.user).toEqual({
    id: '1',
    email: 'fake@fakefunction.nl',
  })
})

TypeScript报错信息

Property 'singleResult' does not exist on type '{ kind: "incremental"; initialResult: GraphQLExperimentalFormattedInitialIncrementalExecutionResult<ObjMap<unknown>, ObjMap<unknown>>; subsequentResults: AsyncIterable<...>; } | { ...; }'.
  Property 'singleResult' does not exist on type '{ kind: "incremental"; initialResult: GraphQLExperimentalFormattedInitialIncrementalExecutionResult<ObjMap<unknown>, ObjMap<unknown>>; subsequentResults: AsyncIterable<...>; }'

解决方案

方案1:类型断言直接指定类型

既然已经通过断言确认了kind为single,可以直接用类型断言明确response.body的类型:

// 断言为single类型的响应体
const singleResponseBody = response.body as { 
  kind: 'single'; 
  singleResult: FormattedExecutionResult<User> 
};

expect(singleResponseBody.singleResult.data.user).toEqual({
  id: '1',
  email: 'fake@fakefunction.nl',
})

方案2:自定义类型守卫实现自动窄化

定义类型守卫函数,让TypeScript自动识别并窄化类型:

import { GraphQLResponseBody, FormattedExecutionResult } from '@apollo/server';

function isSingleResponseBody<T>(body: GraphQLResponseBody<T>): body is {
  kind: 'single';
  singleResult: FormattedExecutionResult<T>;
} {
  return body.kind === 'single';
}

在测试中使用:

if (isSingleResponseBody(response.body)) {
  // 此处TypeScript已自动识别response.body为single类型
  expect(response.body.singleResult.data.user).toEqual({
    id: '1',
    email: 'fake@fakefunction.nl',
  });
} else {
  // 测试场景下可抛出错误,确保响应符合预期
  throw new Error('Expected single-type response body');
}

方案3:条件判断触发自动类型窄化

将expect断言替换为条件判断,让TypeScript自动完成类型窄化:

// 先排除incremental类型的情况
if (response.body.kind !== 'single') {
  throw new Error('Response body is not of type "single"');
}

// 此时TypeScript会自动推断response.body为single类型
expect(response.body.singleResult.data.user).toEqual({
  id: '1',
  email: 'fake@fakefunction.nl',
})

内容的提问来源于stack exchange,提问作者Whyhankee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:13:28