这篇文章将介绍如何在项目中将 i18n 与 Typescript 融合,以便为开发者提供更好的开发体验。更好的开发体验指的是提供键入提示,自动补充,参数类型校验等等,避开低级的错误。
优化前:
优化后:
如果你很清楚如何实现,继续阅读下去可能不会有太大的帮助。
正文开始
回想一下在前端的项目中,i18n 通常出现的形式是存在多份语言映射表,同一个 key 在不同的语言文件中翻译为不同的内容:
// en.json
{
"hello": "Hello"
}
// zh-CN.json
{
"hello": "你好"
}
在需要展示文案的位置,使用 i18n 工具包提供的方法,传递 “key” 来指定需要展示的多语言文本。
<div>{
t("hello")}</div>
React 中常用的 i18n 工具包有react-intl, react-i18next,大致使用方法差不多,这里使用的是 react-i18next 的写法。
问题出现
这里的 t
方法可以接受任意参数,即使传入不存在的 key 值没有任何问题,甚至大部分 i18n 翻译库会自动 fallback 到直接将 key 展示出来。
无疑这里会给低级错误留机会,在 Typescript 中,我们当然不想发生这种情况。
想要告诉 Typescript t
方法接受哪些翻译的 key 值很简单。我们可以将其全部枚举出来,使用 |
符号组合。并声明一个 I18nT
的函数类型。
type TranslateKeys = 'event.title' | 'event.description' | ...
type I18nT = {
(key: TranslateKeys): string
}
应用这个类型和具体使用的工具有关,可能需要声明合并或类型断言的形式来让程序理解 t
的类型。
// 在 i18next 项目中,t 方法的类型是 TFunciton,可以使用声明合并
declare module "i18ne