Type-Safe Internationalization for TypeScript
i18n-ts is a lightweight, type-safe internationalization library designed specifically for TypeScript applications. It allows developers to define translation messages as plain TypeScript objects, leveraging TypeScript's robust type inference system to ensure that message keys and their associated arguments are correctly used at compile time. This approach significantly reduces runtime errors related to missing translations or incorrect parameter usage, a common issue in dynamic i18n systems. The current stable version is 1.0.5, suggesting a relatively mature and stable codebase with a likely slow release cadence. Its key differentiator lies in its deep integration with TypeScript, providing compile-time safety without requiring external build steps or complex configuration files often found in other i18n solutions. It focuses on simplicity and type inference over a feature-rich runtime, making it ideal for projects prioritizing strong typing in their i18n layer.
Common errors
-
TS2339: Property 'nonExistentKey' does not exist on type '{ hello: string; greeting: (name: string) => string; }'.cause Attempting to access a translation key that is not defined in the loaded locale object or has a typo.fixEnsure the translation key exists in the active locale object and matches the exact property name. TypeScript's inference will highlight these issues at compile time. -
TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
cause Providing an argument of the wrong type to a translation function, as defined in your locale object (e.g., calling `greeting(123)` when `greeting` expects a `string`).fixPass arguments to your translation functions that precisely match the type signatures defined in your locale objects. TypeScript provides strong type checking for this. -
TypeError: Cannot read properties of undefined (reading 'translation')
cause The `i18n` object passed to `I18nResolver` is malformed, the selected locale key (e.g., 'de') does not exist within it, or `default` locale is missing.fixVerify that the `i18n` object is correctly structured with defined locale objects (e.g., `en`, `de`) and that the selected locale key matches one of the defined keys. Also, ensure a `default` locale is provided.
Warnings
- gotcha i18n-ts does not provide built-in support for complex i18n features like pluralization, gender, or sophisticated ICU MessageFormat. Users must implement these functionalities manually within their message functions.
- gotcha All translation messages defined as plain TypeScript objects are typically bundled with your application by default. This can lead to increased bundle sizes for applications supporting a large number of locales, as there is no built-in dynamic locale loading mechanism.
- breaking Major version updates (e.g., v2.0.0) could introduce breaking changes to the expected structure of locale objects or the way message functions receive arguments, necessitating updates to your existing translation files.
Install
-
npm install i18n-ts -
yarn add i18n-ts -
pnpm add i18n-ts
Imports
- I18nResolver
const I18nResolver = require('i18n-ts');import { I18nResolver } from 'i18n-ts';
Quickstart
import { I18nResolver } from 'i18n-ts';
const en = {
hello: "Hi!",
greeting: (name: string) => `Hi ${name}`
};
const de = {
hello: "Hallo!",
greeting: (name: string) => `Hallo ${name}`
};
const i18n = {
en: en,
de: de,
default: en
};
// Initialize the resolver with your locales and desired language
const messages = new I18nResolver(i18n, "de").translation;
// TypeScript will infer the precise type of 'messages', providing compile-time safety
console.log(messages.hello); // Output: Hallo!
console.log(messages.greeting("Alice")); // Output: Hallo Alice
// Example of changing the language
const messagesEn = new I18nResolver(i18n, "en").translation;
console.log(messagesEn.hello); // Output: Hi!