ApolloServer配置Context失败,报TS2353类型错误求助
解决ApolloServer初始化时context属性的TS2353类型错误
错误原因
当你通过makeExecutableSchema生成schema并传入ApolloServer时,ApolloServer会使用ApolloServerOptionsWithSchema类型,这个类型不包含context配置项。ApolloServer v4+的设计逻辑是:context属于传输层相关配置,需要绑定到具体的中间件(比如express的expressMiddleware),而不是全局的ApolloServer实例。
解决方案
- 移除ApolloServer实例化代码中的
context属性 - 在
expressMiddleware中配置context,这里的context会被所有HTTP请求的resolvers获取到 - 若需自定义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
相关产品推荐
相关产品推荐

