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

如何为多语言Hook实现严格的TypeScript双维度类型校验?

实现严格的多语言翻译Hook TypeScript类型约束

我正在开发一个多语言应用,希望构建尽可能严格且简洁的TypeScript类型约束。现有代码如下:

//=== Inside my Hook: ===//
interface ITranslation {
   [key:string]:[string, string]
}

const useTranslator = (translations:ITranslation) => {
   const language = useLanguage() // just getting the language setting from another hook

   const translate = (key:keyof typeof translations) => {
      // mapping and returning the right translation
   }

   return translate;
}


//=== Inside the component: ===//
const translation:ITranslation = {
   "something in english": [ "something in german", "something in spanish" ],
   "anotherthing in english": ["anotherthing in german", "anotherthing in spanish"]
}

const translate = useTranslator(translation)

return(
   <Text>{translate("something in english")}</Text>
)

我期望实现两个目标:

  • 当向useTranslator Hook传递含动态键的translation对象时,TypeScript能校验每个属性都是包含两个字符串的数组;
  • 在组件中使用translate函数时,若传入的键不存在于translation对象中,TypeScript能抛出错误。

但目前无法同时实现这两点:若用as const定义translation,传给Hook时没有值类型校验;若用ITranslation类型定义,translate函数参数无键校验。请问是否可行?若可行,该如何实现?


可行,通过泛型约束可以同时满足这两个需求。核心思路是用泛型保留传入对象的具体键类型,同时约束对象的值必须符合[string, string]的结构。

修改Hook实现

将useTranslator改为泛型函数,通过泛型T约束传入的translations必须是键为字符串、值为双元素字符串数组的对象:

//=== Inside my Hook: ===//
// 定义值的类型约束,替代原有的ITranslation接口
type TranslationValue = [string, string];

// 泛型函数,T必须是键为string、值为TranslationValue的对象
const useTranslator = <T extends Record<string, TranslationValue>>(translations: T) => {
  const language = useLanguage(); // 获取当前语言设置

  // translate的参数被约束为T的键类型,自动提示合法键并校验
  const translate = (key: keyof T) => {
    const [german, spanish] = translations[key];
    // 根据language返回对应翻译,示例逻辑:
    switch(language) {
      case 'de': return german;
      case 'es': return spanish;
      default: return key; // 默认返回英文键
    }
  };

  return translate;
};

组件中使用

不需要给translation显式指定类型,让TypeScript自动推断其具体结构(既保留键的字面量类型,又自动校验值是否符合[string, string]):

//=== Inside the component: ===//
// 自动推断类型,若值不是双元素字符串数组会报错
const translation = {
  "something in english": ["something in german", "something in spanish"],
  "anotherthing in english": ["anotherthing in german", "anotherthing in spanish"]
};

// translate的参数会被严格约束为translation的键,传错键直接报错
const translate = useTranslator(translation);

return(
  <Text>{translate("something in english")}</Text>
);

为什么这样有效?

  1. 值类型校验:泛型约束T extends Record<string, TranslationValue>确保传入的每个属性值都是[string, string],不符合时TypeScript会直接报错;
  2. 键类型校验:translate函数的参数key: keyof T直接关联到传入对象的具体键,编辑器会自动提示合法键,传入不存在的键会触发类型错误。

如果需要强制translation的键是字面量类型(避免后续意外修改),可以结合as const,此时泛型约束依然会生效:

const translation = {
  "something in english": ["something in german", "something in spanish"],
  "anotherthing in english": ["anotherthing in german", "anotherthing in spanish"]
} as const;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:44:52