Graphql Yoga与Express集成报错:无匹配重载调用
问题代码
import { createServer } from '@graphql-yoga/node'; import express from 'express'; // create mesh const { schema, getEnveloped } = await getBuiltMesh(); // create express server const app = express(); // create yoga server const server = createServer({ schema: schema, }); // add graphql endpoint app.use('/graphql', server);
报错信息
No overload matches this call. The last overload gave the following
error.
Argument of type 'YogaNodeServerInstance<{ req: IncomingMessage; res: ServerResponse; }, { req: IncomingMessage; }, {}>' is not
assignable to parameter of type 'Application'.
Type 'YogaNodeServer<{ req: IncomingMessage; res: ServerResponse; }, { req: IncomingMessage; }, {}> & ((req:
IncomingMessage, res: ServerResponse) => Promise<...>)' is missing the
following properties from type 'Application': init,
defaultConfiguration, engine, set, and 60 more.ts(2769)
解决方案
1. 核心修改:添加请求体解析中间件 + 类型兼容处理
GraphQL Yoga需要直接处理原始JSON请求体,而Express默认不会解析这类请求体,同时TypeScript类型系统无法自动兼容Yoga实例与Express中间件类型,修改代码如下:
import { createServer } from '@graphql-yoga/node'; import express from 'express'; // create mesh const { schema, getEnveloped } = await getBuiltMesh(); // create express server const app = express(); // create yoga server const server = createServer({ schema: schema, }); // 先添加raw中间件解析JSON请求体,再挂载Yoga服务器(添加类型断言解决类型不兼容) app.use('/graphql', express.raw({ type: 'application/json' }), server as express.RequestHandler);
2. 原理说明
- 请求体解析:Express默认的
express.json()会解析JSON并将结果挂载到req.body,但Yoga需要直接读取原始请求流,因此必须用express.raw({ type: 'application/json' })来保留原始请求体。 - 类型兼容:Yoga服务器实例本身符合Express请求处理函数签名,但TypeScript类型定义未显式对齐,通过
as express.RequestHandler的类型断言可绕过类型检查,且不影响运行逻辑。
3. 替代方案(使用Yoga的请求监听器)
如果不想用类型断言,可以直接调用Yoga实例的requestListener属性:
app.use('/graphql', express.raw({ type: 'application/json' }), server.requestListener);
内容的提问来源于stack exchange,提问作者Norbert von Panthen

