type GetI18nKey<T, K extends keyof T = keyof T> =
K extends string ?
T[K] extends Record<string, unknown> ?
`${K}.${GetI18nKey<T[K]>}`
: K
: never
type I18nKey = GetI18nKey<LocaleMessage>
type RouteKey = GetI18nKey<LocaleMessage, 'route'>
type TableKey = GetI18nKey<LocaleMessage, 'table'>
规划翻译字段类型,通用的,枚举的。
一般枚举的 我会先提取这样的。
上面注释会被 i18n-ally 识别的,然后提取到翻译。
代码层, 页面(模板)层。 注入一个 $enumTrans 的翻译对象。
$enumTrans 包含各种枚举, 可以通过一些 js 动态功能 + ts 类型处理。
类似这样,
一:单文件自定义块
优点是可以快速搞定,AI 工具一直 Tab 就行了,大部分时间花在看 vue-i18n 文档,缺点是零散在几十几百个 vue 文件里,适合那种特别老的项目,不想额外管理 i18n 文件,且页面和文字几乎不会再改动。
二:json 文件
重构 i18n 确实烦人,但是如果还想正常迭代项目只能重构。将所有中文文本抽离出来,大致分类一下,再让 AI 一次性翻译完英文,然后手动一个个去替换原始文本 t('xxx.yyy')。我建议二层嵌套就行,顶多三层嵌套。
三:ts 文件
事先声明我这属于瞎折腾,用 json 方案就行了。
i18n-ally 和 vue-i18n 在 ts 文件上都有一些坑,搞了好久总算能用了,但是跟 json 方案比差不了多少。
这是我的 i18n-ally 的 vscode 配置文件
这样就能正常识别 ts 文件
这是我的 i18n/index.ts 文件
LocaleMessage 是我的翻译文本类型
大概这样
然后可以递归得到所有 key 的联合类型
在你需要硬编码比如路由元信息等地方用 I18nKey 类型进行限定就能完全消除硬编码