Fluent is an great DSL for localization. This project allows you to generate TypeScript types for yours .ftl files.
Npm:
npx fluent2tsBun:
bunx fluent2tsYarn:
yarn dlx fluent2tsPnpm:
pnpm exec fluent2tsAfter that, the locales.types.ts file is automatically generated in the src folder. You can also change this path by specifying the -o (or --output) argument. For example - npx fluent2ts -o src/some/i18n.ts.
You can also specify the glob pattern to search for .ftl files are specified after the command. For example npx fluent2ts locales/**/*.ftl. By default it is **/*.ftl.
You can also use watch mode and regenerate the types when the file has been modified. To do this, simply specify the --watch (or -w) argument. For example, npx fluent2ts -w.
2024-05-28.21-03-51.mp4
For example for this:
# Simple things are simple.
hello-user = Hello, {$userName}!
# Complex things are possible.
shared-photos =
{$userName} {$photoCount ->
[one] added a new photo
*[other] added {$photoCount} new photos
} to {$userGender ->
[male] his stream
[female] her stream
*[other] their stream
}.The following will be generated:
import type {
FluentBundle,
FluentVariable,
Message as FluentMessage,
// @ts-ignore
} from "@fluent/bundle";
export interface LocalesMap {
"hello-user": {
userName: FluentVariable;
};
"shared-photos": {
userName: FluentVariable;
photoCount: FluentVariable;
userGender: FluentVariable;
};
}
export interface Message<Key extends keyof LocalesMap> extends FluentMessage {
id: Key;
}
export interface TypedFluentBundle extends FluentBundle {
getMessage<Key extends keyof LocalesMap>(key: Key): Message<Key>;
formatPattern<Key extends keyof LocalesMap>(
key: Key,
...args: LocalesMap[Key] extends never ? [] : [args: LocalesMap[Key]]
): string;
formatPattern<Key extends keyof LocalesMap>(
key: Key,
args: LocalesMap[Key] extends never ? null : LocalesMap[Key],
errors?: Error[] | null
): string;
}