TypeScript Express项目表单验证翻译时出现req.t不是函数错误
解决Express+TypeScript中i18next req.t在表单验证里的报错问题
问题场景
TypeScript Express项目中配置了i18next多语言中间件,尝试在express-validator的checkSchema表单验证规则里通过req.t()生成多语言错误信息,提交表单时触发报错:
TypeError: req.t is not a function
报错堆栈:
TypeError: req.t is not a function at errorMessage (D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\validation\authSchemas.ts:8:97) at Context.addError (D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\node_modules\express-validator\lib\context.js:69:54) at D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\node_modules\express-validator\lib\context-items\standard-validation.js:20:25 at Array.forEach (<anonymous>) at StandardValidation.run (D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\node_modules\express-validator\lib\context-items\standard-validation.js:17:16) at D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\node_modules\express-validator\lib\chain\context-runner-impl.js:41:39 at Array.map (<anonymous>) at ContextRunnerImpl.run (D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\node_modules\express-validator\lib\chain\context-runner-impl.js:34:70) at middleware (D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\node_modules\express-validator\lib\middlewares\check.js:15:26) at Layer.handleRequest (D:\Documents\_Dokumenti\Projekti\_Master\Real Estate App\Node\secure\realestate\node_modules\router\lib\layer.js:152:17)
排查原因
- i18next中间件未挂载到Express app:仅初始化i18next实例,但未通过
i18next-http-middleware的handle方法将多语言能力注入到Express请求对象中,导致req.t不存在。 - 中间件顺序错误:如果表单验证中间件在i18next中间件之前执行,请求对象还未被注入
t方法,会触发报错。 - 翻译文件路径配置错误:相对路径
../lang/{{lng}}/{{ns}}.json可能因运行时工作目录不同,导致无法加载翻译文件。
解决方案
1. 完善i18next中间件配置,添加Express挂载逻辑
修改realestate/middleware/localization.ts,导入i18next-http-middleware的handle方法,并导出挂载中间件的函数:
import i18next from "i18next"; import Backend from "i18next-fs-backend"; import { LanguageDetector, handle } from "i18next-http-middleware"; import { Express } from "express"; i18next .use(Backend) .use(LanguageDetector) .init({ lng: "sr", ns: ["messages", "fields"], fallbackLng: "en", backend: { // 使用__dirname拼接绝对路径,避免相对路径问题 loadPath: `${__dirname}/../lang/{{lng}}/{{ns}}.json` }, debug: false // 调试时可设为true,查看翻译文件加载日志 }); // 导出用于挂载到Express app的函数 export const initLocalization = (app: Express) => { app.use(handle(i18next)); };
2. 调整中间件挂载顺序
在项目入口文件(如app.ts/server.ts)中,先挂载i18next中间件,再挂载表单验证和路由中间件:
import express from "express"; import { initLocalization } from "./middleware/localization"; import { registerSchema } from "./validation/authSchemas"; import authRoutes from "./routes/auth"; const app = express(); // 1. 优先挂载i18next中间件,确保所有请求都能访问req.t initLocalization(app); // 2. 挂载Express内置中间件 app.use(express.urlencoded({ extended: true })); app.use(express.json()); // 3. 挂载表单验证和路由(验证中间件必须在i18next之后) app.post("/registracija", registerSchema, authRoutes.register);
3. 优化验证规则中的翻译逻辑(可选兜底)
为避免极端情况报错,可在checkSchema中增加req.t存在性判断:
export const registerSchema = checkSchema({ email: { notEmpty: { errorMessage: (_value, { req }) => { if (!req.t) return "Email is required"; return req.t("messages:field.required", { attr: req.t("fields:email") }); } }, isEmail: { errorMessage: (_value, { req }) => { if (!req.t) return "Invalid email format"; return req.t("messages:email.email", { attr: req.t("fields:email") }); } } } });
4. 验证翻译文件路径
确保目录结构正确:
realestate/ ├── lang/ │ ├── sr/ │ │ ├── messages.json │ │ └── fields.json │ └── en/ │ ├── messages.json │ └── fields.json ├── middleware/ │ └── localization.ts
验证步骤
- 重启Express服务器
- 提交空邮箱或无效格式的邮箱表单,查看错误信息是否正确翻译,且无
req.t is not a function报错。
内容的提问来源于stack exchange,提问作者IgorArnaut
相关产品推荐
相关产品推荐

