環境
i18next: v25.3.x
react-i18next: v15.6.x
はじめに
React + TypeScript + i18nextの構成で、JSONリソースから型情報を自動生成し、型推論を効かせるための方法をまとめました。
必要な情報が公式ドキュメントだけでは分からなかったり、GitHub、Stack Overflowにバラバラに載っていたりしたので、調べるのに少し苦労しました。
そこで、自分の備忘録も兼ねて、ここにまとめておこうと思います。
この記事は、やりたいことに対してすぐに答えが見つかる逆引き形式になっています。
やりたいこと
型推論を有効化
i18nextの型定義をTypeScriptに認識させ、JSONのキーを補完できるようにします。
import "i18next";
import ja from "../i18n/ja/translation.json";
declare module "i18next" {
interface CustomTypeOptions {
defaultNS: "ja";
resources: {
ja: typeof ja;
};
}
}
参考:
https://zenn.dev/sjbworks/articles/80b623a0e31a1b
https://www.i18next.com/overview/typescript
keyの型
JSONリソースのkeyに該当する型についてです。
import { useTranslation } from "react-i18next";
{
// JSX内
const { t } = useTranslation();
const translate = (key: string): string => {
return t(key);
// Argument of type '[string]' is not assignable to parameter of type '[key: string | string[], options: TOptionsBase & $Dictionary & { defaultValue: string; }] | [key: string | string[], defaultValue: string, options?: (TOptionsBase & $Dictionary) | undefined] | [key: ...]'.
}
}
import type { ParseKeys } from "i18next"; // インポート
import { useTranslation } from "react-i18next";
{
// JSX内
const { t } = useTranslation();
// i18nextが提供する型ParseKeysをキーに指定する
const translate = (key: ParseKeys): string => {
return t(key);
}
}
参考:
https://github.com/i18next/react-i18next/issues/1530#issuecomment-1722288325
keyの型ガード関数
ParseKeys型を使うことで、keyの存在をチェックする型ガード関数を作ることができます。
この例では、keyが存在すれば変換後の文字列を返し、存在しなければ引数をそのまま返すようにしています。
import { useTranslation } from "react-i18next";
{
// JSX内
const { t } = useTranslation();
const getLabel = (key: string): string => {
return t(key);
// Argument of type '[string]' is not assignable to parameter of type '[key: "...'.
}
}
import type { ParseKeys } from 'i18next'; // インポート
import { useTranslation } from "react-i18next";
{
// JSX内
const { t, i18n } = useTranslation();
// string型をParseKeys型に絞り込む型ガード関数
const isParseKeys = (arg: string): arg is ParseKeys => i18n.exists(arg);
// 実際にキーが存在するかチェックする
const getLabel = (key: string): string => {
if (isParseKeys(key)) {
return t(key);
} else {
console.warn(`i18n key "${key}" does not exist.`);
return key; // キーが見つからない場合は引数keyをそのまま返す
}
}
}
参考:
https://stackoverflow.com/a/72471339
https://www.i18next.com/overview/api#exists
t関数の型
JSXの中では、useTranslationフックを使うことでt関数を簡単に利用できますが、コンポーネントの外に切り出した関数などで利用したい場合もあります。
そういうケースで、t関数の型を明示的に指定する方法です。
import type { TFunction } from "i18next"; // インポート
// i18nextが提供する型TFunctionを引数に指定する
const mapOptions = (definition: Definition[], t: TFunction): Option[] => {
return options.map(opt => ({
label: t(opt.labelKey),
value: opt.value,
}));
}
参考:
https://stackoverflow.com/a/78266163
さいごに
今回は、react-i18nextにおける型推論の活用方法をまとめました。
この記事が、同じ課題を持つ誰かの助けになれば幸いです。
もし新しい情報や、より良い方法を見つけたら、この記事に随時追加していく予定です。