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

Fastify Typescript项目req.body为unknown无法访问属性怎么解决

注意:你当前定义的路由为GET方法,HTTP规范中GET请求不建议携带请求体,Fastify默认也不会解析GET请求的body,若你是要提交用户数据,请先将路由的method修改为POST或PUT。

类型报错解决方案

你遇到的类型报错是因为Fastify默认将req.body定义为unknown类型,需要显式声明请求体结构才能让TS正确推断类型,以下两种方案都适配你当前用fastify.route传入RouteOptions的写法,不需要改为app.get()类的写法。

方案1:原生泛型声明(无需额外依赖)

首先定义请求相关的TS类型:

// 定义请求体结构
interface UserCreateBody {
  name: string
  lastName: string
  dateOfBirth: string
  addressLine: string
  zipCode: string
  city: string
  country: string
}
// 定义URL参数结构(对应路由中的:id)
interface UserRouteParams {
  id: string
}

给RouteHandlerMethod传入泛型指定请求结构:

const handler: RouteHandlerMethod<{
  Params: UserRouteParams
  Body: UserCreateBody
}> = async (req, res) => {
  // 此时req.body会自动推断为UserCreateBody类型,不会出现属性不存在的报错
  const { name, lastName, dateOfBirth, addressLine, zipCode, city, country } = req.body
  const userId = req.params.id // 也可以正确推断id的类型
  // 后续业务逻辑
}

给RouteOptions传入相同的泛型保持类型一致性:

const route: RouteOptions<{
  Params: UserRouteParams
  Body: UserCreateBody
}> = {
  method: 'POST',
  url: '/user/:id',
  handler,
  preValidation,
  // 可继续配置schema做运行时校验,和TS类型形成双重保障
  schema: {
    body: {
      type: 'object',
      required: ['name', 'lastName', 'dateOfBirth', 'addressLine', 'zipCode', 'city', 'country'],
      properties: {
        name: { type: 'string' },
        lastName: { type: 'string' },
        // 其余字段的schema规则
      }
    }
  }
}

方案2:Typebox 同步定义类型和校验规则(适合需要运行时校验的场景)

如果不想同时维护TS类型和JSON Schema,可以用Fastify官方推荐的@sinclair/typebox库,一次定义同时生成TS类型和运行时校验schema:

  1. 安装依赖
npm i @sinclair/typebox
  1. 代码示例
import { Type, Static } from '@sinclair/typebox'

// 定义结构,自动生成对应TS类型
const UserCreateBodySchema = Type.Object({
  name: Type.String(),
  lastName: Type.String(),
  dateOfBirth: Type.String({ format: 'date' }),
  addressLine: Type.String(),
  zipCode: Type.String(),
  city: Type.String(),
  country: Type.String()
})
type UserCreateBody = Static<typeof UserCreateBodySchema>

const UserRouteParamsSchema = Type.Object({
  id: Type.String()
})
type UserRouteParams = Static<typeof UserRouteParamsSchema>

// handler和RouteOptions泛型写法和方案1一致,schema直接传入定义好的schema对象即可
const route: RouteOptions<{
  Params: UserRouteParams
  Body: UserCreateBody
}> = {
  method: 'POST',
  url: '/user/:id',
  handler,
  schema: {
    params: UserRouteParamsSchema,
    body: UserCreateBodySchema
  }
}
之前配置schema不生效的原因

Fastify默认的JSON Schema仅用于运行时参数校验,不会自动关联TS类型,如果你希望配置schema后自动推断请求类型,可以安装对应的类型提供器,比如@fastify/type-provider-typebox,配置后无需手动声明泛型即可通过schema自动推断req的类型,配置方式如下:

  1. 安装依赖
npm i @fastify/type-provider-typebox
  1. 初始化Fastify实例时指定类型提供器
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'

const buildServer = (options = {}) => {
  const app = fastify(options).withTypeProvider<TypeBoxTypeProvider>()
  app.register(routesApiV1, { prefix: '/api'});
  return app;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:15:03