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:
- 安装依赖
npm i @sinclair/typebox
- 代码示例
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的类型,配置方式如下:
- 安装依赖
npm i @fastify/type-provider-typebox
- 初始化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
相关产品推荐
相关产品推荐

