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

ApolloServer配置Context失败,报TS2353类型错误求助

解决ApolloServer初始化时context属性的TS2353类型错误

错误原因

当你通过makeExecutableSchema生成schema并传入ApolloServer时,ApolloServer会使用ApolloServerOptionsWithSchema类型,这个类型不包含context配置项。ApolloServer v4+的设计逻辑是:context属于传输层相关配置,需要绑定到具体的中间件(比如express的expressMiddleware),而不是全局的ApolloServer实例。

解决方案

  1. 移除ApolloServer实例化代码中的context属性
  2. 在expressMiddleware中配置context,这里的context会被所有HTTP请求的resolvers获取到
  3. 若需自定义Context类型,替换默认的BaseContext即可

修改后的完整代码

import { ApolloServer } from '@apollo/server';
import { typeDefs } from './schema/type-defs';
import { resolvers } from './schema/resolvers';
import { createServer } from 'http';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';
import express from 'express';
import { BaseContext } from "@apollo/server";
import { expressMiddleware } from "@apollo/server/express4";
import bodyParser from 'body-parser';

// 可选:自定义Context类型
interface MyContext extends BaseContext {
  req: Express.Request;
  res: Express.Response;
}

const app = express();
const httpServer = createServer(app);

const schema = makeExecutableSchema({ typeDefs, resolvers });

const wsServer = new WebSocketServer({
  server: httpServer,
  path: '/graphql',
});
const serverCleanup = useServer({ schema }, wsServer);

// 移除了context属性
const server = new ApolloServer<MyContext>({
  schema,
  plugins: [
    ApolloServerPluginDrainHttpServer({ httpServer }),
    {
      async serverWillStart() {
        return {
          async drainServer() {
            await serverCleanup.dispose();
          },
        };
      },
    }
  ],
});

(async () => {
  await server.start();
  httpServer.listen(4000, () => {
    console.log(`Query endpoint ready at http://localhost:4000/graphql`);
    console.log(`Subscription endpoint ready at ws://localhost:4000/subscriptions`);
  });
  // 在expressMiddleware中配置context
  app.use('/graphql', bodyParser.json(), expressMiddleware(server, {
    context: async ({ req, res }) => ({ req, res }),
  }));
})();

补充说明

  • 如果需要给WebSocket订阅配置context,要在useServer的参数中添加context字段,比如:
    const serverCleanup = useServer({ 
      schema,
      context: async (ctx) => {
        // 这里处理WebSocket的context逻辑
        return { ...ctx };
      },
    }, wsServer);
    
  • 自定义Context类型后,resolvers中也可以指定该类型,获得完整的类型提示:
    const resolvers = {
      Query: {
        hello: (_parent: unknown, _args: unknown, context: MyContext) => {
          // 这里可以获取context.req和context.res的类型提示
          return 'Hello World';
        },
      },
    };
    

内容的提问来源于stack exchange,提问作者João Cardoso

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:16:02