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

Express+TS项目中i18n的request.__()返回Undefined求助

解决Express+TypeScript项目中i18n request.__() 返回undefined的问题

问题排查与修复步骤

1. 检查locales目录路径与编译复制逻辑

当前代码中path.join(__dirname, 'locales')依赖编译后的目录结构,如果locales文件夹未被复制到编译输出目录(比如dist),i18n会找不到语言文件,导致request.__()返回undefined。

修复方案:
在tsconfig.json中添加配置,确保编译时复制locales文件夹:

{
  "compilerOptions": {
    // 保留原有配置
  },
  "include": [
    "src/**/*",
    "locales/**/*"
  ],
  "exclude": ["node_modules"]
}

如果使用nodemon等开发工具,需配置监听locales文件夹并同步更新。

2. 调整i18n初始化逻辑

手动调用i18n.setLocale('en')的时机错误,应该通过配置项设置默认语言,确保中间件初始化时正确绑定到request对象。

修复后的app.ts片段:

const i18n = new I18n({
  locales: ['en', 'de'],
  directory: path.join(__dirname, 'locales'),
  updateFiles: false,
  defaultLocale: 'en' // 用配置项设置默认语言,替代手动setLocale
});

app.use(i18n.init);
// 移除i18n.setLocale('en')

3. 补充TypeScript类型定义

i18n未自带TS类型,需扩展Express的Request接口,避免类型报错同时确保方法正常识别:

在项目中创建types/i18n.d.ts文件:

declare namespace Express {
  interface Request {
    __: (key: string, ...args: any[]) => string;
    __n: (key: string, count: number, ...args: any[]) => string;
  }
}

并在tsconfig.json的include中添加该类型文件:

"include": [
  "src/**/*",
  "locales/**/*",
  "types/**/*"
]

4. 验证语言文件格式

确保locales/en.json等文件格式正确,无语法错误(如逗号遗漏、引号不匹配),你的现有文件格式是正确的,可跳过此步。

5. 可选:添加动态语言切换逻辑

若需根据请求头自动切换语言,可在i18n中间件后添加:

app.use((req, res, next) => {
  const acceptLang = req.headers['accept-language'];
  if (acceptLang) {
    const locale = acceptLang.split(',')[0];
    if (['en', 'de'].includes(locale)) {
      req.setLocale(locale);
    }
  }
  next();
});

修复后完整示例

app.ts

import { json } from 'body-parser';
import dotenv from 'dotenv';
dotenv.config();
import express from 'express';
import { I18n } from 'i18n';
import cors from 'cors';
import routes from './routes';
import path from 'path';

const app = express();

const i18n = new I18n({
  locales: ['en', 'de'],
  directory: path.join(__dirname, 'locales'),
  updateFiles: false,
  defaultLocale: 'en'
});

app.use(i18n.init);
// 可选:根据请求头自动设置语言
app.use((req, res, next) => {
  const acceptLang = req.headers['accept-language'];
  if (acceptLang) {
    const locale = acceptLang.split(',')[0];
    if (['en', 'de'].includes(locale)) {
      req.setLocale(locale);
    }
  }
  next();
});
app.use(json());
app.use(cors());
app.use(routes);

export default app;

用户接口代码

getUserProfile.get(
  '/:id',
  async (request: express.Request, response: express.Response) => {
    try {
      const helloMsg = request.__('Hello');
      const fetchSuccessMsg = request.__('MESSAGES.USER_FETCH');
      console.log(helloMsg); // 应输出"Hello World"

      response.json({ err: 0, message: fetchSuccessMsg });
    } catch (error: any) {
      response.json({ err: 1, message: error.message, error });
    }
  }
);

验证步骤

  1. 确认locales文件夹已复制到编译输出目录(如dist/locales)。
  2. 启动项目,调用/user/profile/:id接口,查看控制台输出是否为"Hello World"。
  3. 设置请求头Accept-Language: de(需提前创建de.json),验证多语言切换功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:09:09