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

Next.js 14 API Handler:如何正确验证Request JSON请求体?

问题:Next.js 14 API请求体验证与ESLint "Unsafe assignment of an any value"警告处理

我正在为开发中的iOS应用构建API,采用Next.js 14实现,大部分功能已正常运行,但对如何正确验证Request的请求体感到困惑。ESLint抛出了各类错误与警告,其中一个我尤为不确定:

Unsafe assignment of an any value

该警告出现在执行const body = await request.json();时。我明白此时json()方法返回any类型,但紧接着我就调用了validateRequest进行验证。我可以将其强制转换为RequestBody类型:const body = await request.json() as RequestBody;,但这似乎违背了验证的初衷,不是吗?请问有什么合适的处理方法吗?

代码示例:

// app/api/route.tsx

interface RequestBody {
  name: string;
}

function validateRequest(object: any): object is RequestBody {
  return (
    (object as RequestBody) && typeof (object as RequestBody).name === "string"
  );
}

export async function POST(request: Request) {
  try {
    // Warning: Unsafe assignment of an `any` value
    const body = await request.json();

    if (!validateRequest(body)) {
      return new Response("Invalid Data", { status: 400 });
    }

    return Response.json({ message: body.name });
  } catch {
    return new Response("Bad Request", { status: 400 });
  }
}
解决方案

这里有几种既符合TypeScript类型安全要求,又不违背运行时验证初衷的处理方式:

1. 用unknown替代any声明请求体类型

request.json()返回any是ESLint警告的核心原因,改用unknown类型可以明确表示我们不确定请求体的结构,同时避免any带来的类型不安全问题。结合类型守卫后,TypeScript会自动在验证通过后推断出正确的类型:

// app/api/route.tsx

interface RequestBody {
  name: string;
}

// 调整验证函数参数为unknown,逻辑更严谨
function validateRequest(object: unknown): object is RequestBody {
  return (
    typeof object === 'object' && 
    object !== null && 
    'name' in object && 
    typeof (object as RequestBody).name === "string"
  );
}

export async function POST(request: Request) {
  try {
    // 声明为unknown消除ESLint警告
    const body: unknown = await request.json();

    if (!validateRequest(body)) {
      return new Response("Invalid Data", { status: 400 });
    }

    // 此时TypeScript已自动推断body为RequestBody类型
    return Response.json({ message: body.name });
  } catch {
    return new Response("Bad Request", { status: 400 });
  }
}

2. 类型断言配合中转(简易方案)

如果不想修改验证函数的参数类型,可以用unknown做中转,再临时断言为any用于验证阶段,这种方式适合快速调整:

export async function POST(request: Request) {
  try {
    const body = await request.json() as unknown;

    if (!validateRequest(body as any)) {
      return new Response("Invalid Data", { status: 400 });
    }

    return Response.json({ message: (body as RequestBody).name });
  } catch {
    return new Response("Bad Request", { status: 400 });
  }
}

3. 使用专业验证库(推荐)

手动编写类型守卫容易遗漏边界情况,使用Zod、Yup这类专门的运行时验证库,能同时实现TypeScript类型推导和严格的运行时校验,彻底解决类型安全和ESLint警告问题。以Zod为例:

import { z } from 'zod';

// 定义Zod校验规则,自动生成对应的TypeScript类型
const RequestBodySchema = z.object({
  name: z.string(),
});

type RequestBody = z.infer<typeof RequestBodySchema>;

export async function POST(request: Request) {
  try {
    const body = await request.json();
    // 验证请求体,不符合规则则直接抛出错误
    const validatedBody = RequestBodySchema.parse(body);
    return Response.json({ message: validatedBody.name });
  } catch (error) {
    return new Response("Invalid Data", { status: 400 });
  }
}

这种方式无需手动维护类型守卫,Zod会自动同步类型定义和校验逻辑,同时ESLint不会再抛出any相关警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:15:23