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

为递归deepTranslate函数实现TypeScript类型转换:I18nObject转string

实现递归翻译函数并保留原对象类型结构(替换I18nObject为string)

完全可行,通过TypeScript的递归条件类型可以精准实现这个需求:既保留原对象的结构,又将所有I18nObject类型替换为string,同时让函数返回类型自动匹配转换后的结构。

步骤1:定义核心类型

首先明确I18nObject以及递归转换的工具类型:

// 定义多语言字段类型
type I18nObject = { [lang: string]: string };

// 递归类型转换:将所有I18nObject替换为string,保留其他结构
type DeepTranslated<T> = 
  T extends I18nObject ? string :
  T extends Array<infer U> ? Array<DeepTranslated<U>> :
  T extends object ? { [K in keyof T]: DeepTranslated<T[K]> } :
  T;

这个工具类型的逻辑:

  • 若输入是I18nObject,直接转为string
  • 若输入是数组,递归处理数组内的每个元素
  • 若输入是普通对象,递归处理对象的每个属性
  • 其他基础类型(如number、boolean)保持不变

步骤2:调整递归翻译函数的类型约束

修改deepTranslate函数,让它的返回类型自动推导为DeepTranslated<T>:

function deepTranslate<T>(obj: T, locale: string): DeepTranslated<T> {
  // 处理null/undefined
  if (obj == null) return obj as DeepTranslated<T>;

  // 匹配I18nObject,返回对应语言的字符串
  if (typeof obj === 'object' && locale in obj && typeof (obj as I18nObject)[locale] === 'string') {
    return (obj as I18nObject)[locale] as DeepTranslated<T>;
  }

  // 处理数组:递归翻译每个元素
  if (Array.isArray(obj)) {
    return obj.map(item => deepTranslate(item, locale)) as DeepTranslated<T>;
  }

  // 处理普通对象:递归翻译每个属性
  if (typeof obj === 'object') {
    const translatedObj: Record<string, unknown> = {};
    for (const key in obj) {
      translatedObj[key] = deepTranslate(obj[key], locale);
    }
    return translatedObj as DeepTranslated<T>;
  }

  // 基础类型直接返回
  return obj as DeepTranslated<T>;
}

步骤3:使用示例验证

// 示例输入类型
type Product = {
  id: number;
  name: I18nObject;
  description: I18nObject;
  tags: I18nObject[];
  details: {
    price: number;
    category: I18nObject;
  };
};

// 模拟从数据库获取的原始数据
const rawProduct: Product = {
  id: 1,
  name: { en: "Apple", fr: "Pomme" },
  description: { en: "Fresh organic apple", fr: "Pomme bio fraîche" },
  tags: [{ en: "Fruit", fr: "Fruit" }, { en: "Organic", fr: "Bio" }],
  details: {
    price: 1.99,
    category: { en: "Food", fr: "Aliment" }
  }
};

// 翻译后自动推导类型:所有I18nObject已转为string,结构完全保留
const frenchProduct = deepTranslate(rawProduct, 'fr');
// frenchProduct类型为:
// {
//   id: number;
//   name: string;
//   description: string;
//   tags: string[];
//   details: {
//     price: number;
//     category: string;
//   };
// }

注意事项

  • 若你的I18nObject有固定的语言键规则(比如仅包含en/fr/de等),可以用类型守卫函数替代简单的locale in obj判断,进一步提升类型准确性。
  • TypeScript递归类型存在默认深度限制(通常为100层),但普通业务场景下完全足够。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:15:35