如何用TypeScript泛型约束翻译字典的多语言键名一致?
用TypeScript泛型约束翻译字典的键一致性
你的核心需求是让翻译字典中各语言对应的子字典键名完全一致,通过泛型可以优雅实现这个约束,无需冗余代码。
原泛型方案的问题
你之前的TranslationDict定义用了两个泛型参数,且O extends K[number]的写法逻辑错误——因为K本身是string类型,K[number]无实际意义,导致无法约束jpn的键与eng对齐。
正确的泛型实现
只需要一个泛型参数来定义所有语言共用的键类型,让每个语言的子字典都基于这个类型约束:
interface TranslationDict<Keys extends string> { eng: Record<Keys, string>; jpn: Record<Keys, string>; // 如需扩展其他语言,直接添加对应字段即可,比如chs: Record<Keys, string> }
手动指定键类型
直接声明泛型参数为键的联合类型,TypeScript会严格校验每个子字典的键:
const translationDict: TranslationDict<'year' | 'month' | 'day' | 'file'> = { eng: { year: "year", month: "month", day: "day", file: "file", }, jpn: { year: "年", month: "月", day: "日", file: "ファイル", file2: "bla", // 触发类型错误:"file2"不在允许的键列表中 }, };
自动推导键类型
如果不想手动写联合类型,可以用辅助函数让TypeScript自动推导键,写法更简洁:
function createTranslationDict<Keys extends string>(dict: TranslationDict<Keys>) { return dict; } // TypeScript会自动从eng的键推导出Keys类型 const translationDict = createTranslationDict({ eng: { year: "year", month: "month", day: "day", file: "file", }, jpn: { year: "年", month: "月", day: "日", file: "ファイル", file2: "bla", // 同样触发类型错误 }, });
对比非泛型方案
非泛型方案需要提前定义cols常量,且每个语言字段都要重复写Record<(typeof cols)[number], string>,冗余且扩展性差。泛型方案只需维护接口定义,添加新语言时仅需在接口中新增一行字段,无需重复约束逻辑。
内容的提问来源于stack exchange,提问作者Wesley Cheek
相关产品推荐
相关产品推荐

