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

如何为Apollo GraphQL子图的Resolver Context设置类型?

Apollo GraphQL子图Resolver Context类型配置方案

问题描述

我有一个简单的Apollo GraphQL子图,想要为Resolver中的context参数设置类型。编写的代码如下:

interface Context {
  dataSources: {
    shopify: Shopify;
  }
}

const server = new ApolloServer({
  schema: buildSubgraphSchema({ 
    typeDefs,
    resolvers: {
      Query: {
        shop(_, _args, ctx: Context) {
          console.log("ctx:", ctx)
        },
      }
    }
  }),
  dataSources: () => ({
    shopify: new Shopify()
  })
});

但自定义的Context接口与Resolver预期类型不兼容,抛出TypeScript错误:

Argument of type '{ typeDefs: any; resolvers: { Query: { shop(_: any, _args: any, ctx: Context): void; }; }; }' is not assignable to parameter of type 'DocumentNode | (GraphQLSchemaModule | DocumentNode)[] | LegacySchemaModule'.
  Types of property 'resolvers' are incompatible.
    Property 'Query' is incompatible with index signature.
      Type '{ shop(_: any, _args: any, ctx: Context): void; }' is not assignable to type 'GraphQLScalarType<unknown, unknown> | { [enumValue: string]: string | number; } | { [fieldName: string]: GraphQLFieldResolver<any, unknown, any, unknown> | { requires?: string | undefined; resolve: GraphQLFieldResolver<...>; }; }'.
        Types of property 'shop' are incompatible.
          Type '(_: any, _args: any, ctx: Context) => void' is not assignable to type 'string | number | GraphQLFieldResolver<any, unknown, any, unknown> | { requires?: string | undefined; resolve: GraphQLFieldResolver<any, unknown, any, unknown>; } | undefined'.
            Type '(_: any, _args: any, ctx: Context) => void' is not assignable to type 'GraphQLFieldResolver<any, unknown, any, unknown>'.
              Types of parameters 'ctx' and 'context' are incompatible.
                Type 'unknown' is not assignable to type 'Context'.ts(2345)

需要知道如何正确设置Context类型,以正常访问接口及数据源。

解决方案

核心是通过泛型参数将自定义Context类型绑定到buildSubgraphSchema和Resolver上,让TypeScript正确识别上下文类型,而非仅在参数上标注类型。

方法一:单个Resolver类型断言

  1. 导入所需类型
import { buildSubgraphSchema, GraphQLFieldResolver } from '@apollo/subgraph';
  1. 绑定Context类型到Resolver
interface Context {
  dataSources: {
    shopify: Shopify;
  }
}

const resolvers = {
  Query: {
    // 使用as断言指定Resolver的上下文类型为Context
    shop: ((_, _args, ctx) => {
      console.log("ctx:", ctx);
      // 可直接访问ctx.dataSources.shopify
      return ctx.dataSources.shopify.getShop();
    }) as GraphQLFieldResolver<any, Context, any>,
  },
};

const server = new ApolloServer({
  // 给buildSubgraphSchema传入泛型参数<Context>
  schema: buildSubgraphSchema<Context>({ typeDefs, resolvers }),
  dataSources: () => ({ shopify: new Shopify() }),
});

方法二:全局Resolver类型映射(推荐)

如果存在多个Resolver,可定义统一的Resolver类型映射,避免重复断言:

import { buildSubgraphSchema, GraphQLFieldResolver } from '@apollo/subgraph';

interface Context {
  dataSources: {
    shopify: Shopify;
  }
}

// 定义全局Resolver类型,绑定Context
type AppResolvers = {
  Query: {
    shop: GraphQLFieldResolver<any, Context, any>;
    // 可添加其他Query字段
  };
  // 可添加Mutation、自定义类型的Resolver
};

// 使用定义好的AppResolvers类型,ctx自动推断为Context
const resolvers: AppResolvers = {
  Query: {
    shop(_, _args, ctx) {
      console.log("ctx:", ctx);
      return ctx.dataSources.shopify.getShop();
    },
  },
};

const server = new ApolloServer({
  schema: buildSubgraphSchema<Context>({ typeDefs, resolvers }),
  dataSources: () => ({ shopify: new Shopify() }),
});

错误原因说明

buildSubgraphSchema默认将上下文类型推断为unknown,而直接在Resolver参数标注Context会导致类型不匹配。通过给buildSubgraphSchema传入泛型<Context>,可让整个Schema的Resolver上下文类型统一为自定义接口,结合GraphQLFieldResolver泛型,TypeScript就能正确识别Resolver参数的类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:51:30