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

自定义Middy中间件结合Zod解析请求体的TypeScript类型错误排查

解决Middy中间件Zod类型不匹配错误

问题场景

自定义Middy中间件用Zod解析event.body并将类型化结果存入请求,但调用中间件时触发TypeScript类型错误:

TS2344: Type '{ email: string; password: string; }' does not satisfy the constraint 'ZodType<any, ZodTypeDef, any>'.   Type '{ email: string; password: string; }' is missing the following properties from type 'ZodType<any, ZodTypeDef, any>': _type, _output, _input, _def, and 29 more.

错误原因

调用parseBody时手动传入了schemaType作为泛型参数,而schemaType是Zod解析后的普通对象类型,但parseBody的泛型约束要求传入的是ZodType(即Zod schema本身的类型),两者类型不匹配导致报错。

修复方案

1. 移除手动指定的泛型参数

调用parseBody时不需要手动传泛型,TypeScript会自动根据传入的schema推导正确的Zod类型,避免类型混淆。

2. 优化中间件泛型定义(可选,提升可读性)

调整TypedAPIGatewayProxyEvent和parseBody的泛型参数,让逻辑更直观:泛型直接对应解析后的类型,而非Zod schema类型。

修正后的完整代码

中间件部分

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import middy from '@middy/core';
import z, { ZodType } from 'zod';

// 调整泛型:直接接受解析后的类型T
export interface TypedAPIGatewayProxyEvent<T> extends APIGatewayProxyEvent {
  middy: {
    event: {
      typedBody: T;
    };
  };
}

export const parseBody = <T>(
  schema: ZodType<T>
): middy.MiddlewareObj<TypedAPIGatewayProxyEvent<T>, APIGatewayProxyResult> => {
  const before: middy.MiddlewareFn<TypedAPIGatewayProxyEvent<T>, APIGatewayProxyResult> = async (request): Promise<void> => {
    // 确保body已被jsonBodyParser解析为对象
    const typedBody = schema.parse(request.event.body);
    // 简化对象赋值逻辑
    request.event.middy = {
      ...request.event.middy,
      event: {
        ...request.event.middy?.event,
        typedBody
      }
    };
  };

  return { before };
};

Handler部分

import { APIGatewayProxyResult } from 'aws-lambda';
import middy from '@middy/core';
import { jsonBodyParser } from '@middy/http-json-body-parser';
import z, { TypeOf } from 'zod';
import { TypedAPIGatewayProxyEvent, parseBody } from './your-middleware-file';

const schema = z.object({
  email: z.string(),
  password: z.string(),
});

export type SchemaType = TypeOf<typeof schema>;

export const handler = async (input: TypedAPIGatewayProxyEvent<SchemaType>): Promise<APIGatewayProxyResult> => {
  const typedBody = input.middy.event.typedBody;
  
  return {
    statusCode: 200,
    body: JSON.stringify({
      email: typedBody.email,
      password: typedBody.password
    })
  };
};

// 调用parseBody时无需手动指定泛型,TS自动推导
export const handlerWithMiddleware = middy(handler)
  .use(jsonBodyParser())
  .use(parseBody(schema));

关键说明

  • 移除parseBody<SchemaType>(schema)中的泛型参数后,TS会根据传入的schema自动识别其对应的Zod类型,并推导解析后的T类型。
  • 调整TypedAPIGatewayProxyEvent的泛型为解析后的类型,让handler的输入类型更直观,无需再关联Zod schema类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:37:48