Use i18n with TypeScript checks

victor zhang - Jun 28 - - Dev Community

I tried a simple way to check i18n resources with TypeScript to reduce errors. Here share it with you guys.

Steps

  • Firstly, enable resolveJsonModule in your tsconfig.json
{
    "compilerOptions": {
        "resolveJsonModule" true
        // ...
    }
    // ...
}
Enter fullscreen mode Exit fullscreen mode
  • Define the type for locales
export type Locale = 'en_US' | 'zh_CN'
Enter fullscreen mode Exit fullscreen mode
  • Define the type for messages
export type Messages<T> = {
    [locale in Locale]: T
}
Enter fullscreen mode Exit fullscreen mode
  • Define the type for your resource
export type AboutMessage = {
   label: {
       name: string
       version: string
   }
   tip: {
       feedback: string
   }
}
Enter fullscreen mode Exit fullscreen mode
  • Edit resource json file
{
    "en_US": {
        "label": {
            "name": "My App",
            "version": "Version",
        },
        "tip": {
            "feedback": "This is a feedback link"
        }
    },
    "zh_CN": {
        "label": {
            "name": "我的应用",
            "version": "版本",
        },
        "tip": {
            "feedback": "这是反馈链接"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  • And then, define t() function
import resource "../app-resource.json"

// Use this to check if your resource file is correct
const messages: Messages<AboutMessage> = resource

// Define a function key to get snippet tips while invoking t()
type Key = (msg: AboutMessage) => string

export function t(key: Key, locale: Locale) {
    try {
        return key?.(messages[locale])
    } catch { /* ignored */ }
    try {
        return key?.(messages['en_US'])
    } catch { /* ignored again */ }
    return null
}
Enter fullscreen mode Exit fullscreen mode
  • Finally, you can use it like this, or integrate it into other frameworks
const feedbackTip = t(msg => msg.tip.feedback, 'en_US')
Enter fullscreen mode Exit fullscreen mode

Real Project

The above is just a simple example of my idea, you can extend it according to your project.

And I applied it to my own project Time Tracker which is a browser extension helping people track the time spent on each website.

Thanks for reading

.