如何为Fastify内联路由处理器创建包装函数并保留类型推断?
解决Fastify路由包装函数丢失类型推断的问题
核心问题
你当前的泛型写法会破坏Fastify基于Schema的自动类型推断——TypeScript需要先推断myWrapper的<RQ, RP>泛型参数,再处理fastify.post的上下文类型,导致参数类型无法从Schema传递到内联处理器中。
解决方案
方案1:通用类型复用写法
使用TypeScript的Parameters和ReturnType工具类型,让包装函数完全复用传入处理器的参数和返回类型,确保类型推断能穿透包装器:
const myWrapper = <T extends (...args: any[]) => Promise<any>>(handler: T) => { return async (...args: Parameters<T>): ReturnType<T> => { // 在这里添加包装逻辑(比如日志、全局错误捕获等) return await handler(...args); }; };
方案2:Fastify类型对齐写法
如果你希望明确对齐Fastify的路由处理器类型,可以导入FastifyRequestHandler并约束泛型参数:
import type { FastifyRequestHandler } from 'fastify'; const myWrapper = <Handler extends FastifyRequestHandler>(handler: Handler): Handler => { return async (req, rep) => { // 包装逻辑 await handler(req, rep); } as Handler; };
使用效果
现在你的路由代码中,request和reply的类型会自动从Schema推断出来,不会再变成unknown:
fastify.post( 'v1/article', { schema: { body: { type: 'object', properties: { title: { type: 'string' } }, required: ['title'] } } }, myWrapper(async (request, reply) => { // request.body.title 会被正确推断为 string 类型 // reply 的类型也会保持 FastifyReply 的完整类型 reply.send("ok"); }) );
原理说明
这两种写法的核心都是让包装函数不提前声明泛型参数,而是从传入的处理器函数反向推断类型,从而保留Fastify基于Schema生成的上下文类型信息。TypeScript会先处理fastify.post的Schema推断,再把生成的处理器类型传递给myWrapper,最终让内联处理器的参数类型完全正确。
内容的提问来源于stack exchange,提问作者Bright Lee
相关产品推荐
相关产品推荐

