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
相关产品推荐
相关产品推荐

