Fastify中request.query无法自动推断Schema类型的问题
Fastify + TypeScript 请求参数类型推断失败问题解决
问题描述
我是Fastify结合TypeScript的新手,在代码中执行const {name} = req.query时出现类型错误:Property 'name' does not exist on type 'unknown'.ts(2339)。疑惑定义的Schema是否应该自动为name提供类型推断,还是需要手动为req变量添加类型?
相关代码与配置
路由代码
import { Type } from '@sinclair/typebox'; import { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox' import { FastifyInstance } from 'fastify'; const plugin: FastifyPluginAsyncTypebox = async function(fastify: FastifyInstance) { fastify.get('/', { schema: { querystring: Type.Object({ name: Type.String({ default: 'world' }) }), response: { 200: Type.Object({ hello: Type.String() }) } } }, (req) => { const { name } = req.query; return { hello: name }; }); fastify.post('/', { schema: { body: Type.Object({ name: Type.String() }), response: { 200: Type.Object({ hello: Type.String() }) } } }, async (request) => { const { name } = request.body; return { hello: name || 'world' }; }); } export default plugin;
tsconfig.json
{ "extends": "fastify-tsconfig", "compilerOptions": { "outDir": "build", "target": "es2018", "lib": ["es2018"] } }
package.json
{ "name": "fastify", "version": "1.0.0", "main": "index.js", "scripts": { "build": "tsc -p tsconfig.json", "start": "node index.js" }, "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { "fastify": "^4.27.0" }, "devDependencies": { "@fastify/autoload": "^5.8.2", "@fastify/swagger": "^8.14.0", "@fastify/swagger-ui": "^3.0.0", "@fastify/type-provider-typebox": "^4.0.0", "@sinclair/typebox": "^0.32.30", "@tsconfig/recommended": "^1.0.6", "@types/node": "^20.12.11", "fastify-tsconfig": "^1.0.0", "typescript": "^5.4.5" } }
原因分析与解决方案
原因
你导入的FastifyInstance来自fastify核心包,这个默认实例没有集成TypeBox的类型解析能力,导致req.query和req.body的类型被推断为unknown,自然无法识别Schema中定义的name属性。
解决步骤
只需要修改FastifyInstance的导入来源,从@fastify/type-provider-typebox包中导入该类型,Fastify就会自动根据你定义的Schema为请求对象生成精确的类型,无需手动为req添加类型。
修改后的代码
import { Type } from '@sinclair/typebox'; // 从type-provider-typebox同时导入FastifyPluginAsyncTypebox和FastifyInstance import { FastifyPluginAsyncTypebox, FastifyInstance } from '@fastify/type-provider-typebox' const plugin: FastifyPluginAsyncTypebox = async function(fastify: FastifyInstance) { fastify.get('/', { schema: { querystring: Type.Object({ name: Type.String({ default: 'world' }) }), response: { 200: Type.Object({ hello: Type.String() }) } } }, (req) => { const { name } = req.query; // 类型推断正常,无报错 return { hello: name }; }); fastify.post('/', { schema: { body: Type.Object({ name: Type.String() }), response: { 200: Type.Object({ hello: Type.String() }) } } }, async (request) => { const { name } = request.body; // 类型推断正常 return { hello: name || 'world' }; }); } export default plugin;
补充说明
当前你的tsconfig.json和package.json配置版本兼容,无需额外调整。修改导入来源后,TypeScript就能通过Schema自动推断请求参数的类型,实现类型安全的路由处理。
内容的提问来源于stack exchange,提问作者cornstar94
相关产品推荐
相关产品推荐

