TypeScriptでreact-native-i18nを型安全に扱う

こんにちは。モバイルエンジニアの@hotchemiです。

今回は先日オープンソースとして公開したreact-native-i18n-tsについて簡単にご紹介できればと思います。

モチベーション

React Nativeで開発していくにあたり文字列リソースのInternationalizationにはreact-native-i18nを使う事が殆どだと思いますが、アプリの規模が大きくなっていくに辺り開発体験を阻害する以下の様な問題点が生じてきました。

  • 長いkey名を思い出せず補完も効かないので定義ファイルとソースコードを行ったり来たりせざるを得ない
  • 実行時にしかエラーを検知できないので間違ったkey名でも気づかない事がある

f:id:quipper-ja:20180507170901p:plain
間違ったkey名を指定した場合

これらの課題を解決する為に、AndroidR.javaに倣い「IDE補完の恩恵を受けれる事」「コンパイル時に間違ったエラーを検知できる事」を実現するツールがreact-native-i18n-tsです。

Quipperではフロントエンドの新規開発にはTypeScriptを利用している為、このライブラリもTypeScriptの利用を前提としています。メカニズムとしては非常に単純で、jsonもしくはJSのobjectをparseしその情報を元にd.tsファイルを生成するだけです。

使い方

まずyarn add -D react-native-i18n-tsdependencyを追加して頂き以下の設定をpackage.jsonに追加します。modelで読み込むファイルを指定し、outputDirで型定義ファイルの出力先を指定します。

"react-native-i18n-ts": {
  "model": "./src/locale/languages/en.json",
  "outputDir": "./typings"
}

次にoutputDirで指定したディレクトリをtsconfig.jsonfilesGlobに追加します。

"filesGlob": [
  "typings/*.d.ts",
],

最後にコマンドを実行する為にpackage.jsonのscriptsに以下を追加します。

"scripts": {
  "i18n-ts": "i18n-ts",
  "i18n-ts:watch": "i18n-ts -w"
}

以上で設定は完了です。yarn i18n-tsを実行すると以下の様な型定義ファイルが生成されます。

declare module "react-native-i18n" {
    var fallbacks: boolean;
    var translations: {
        [keys: string]: any;
    };
    function t(key: "common.cancel", opts: {
        value: any;
    }): string;
    function t(key: "common.ok"): string;
}

// for json loading
declare module "*.json" {
    const value: any;
    export default value;
}

この型定義ファイルはソースコード管理に含めても含めなくてもどちらもで良いと考えます。-wオプションをつけるとwatch modeとしてモデルの変更を検知するのでローカルで開発時に利用してもいいですし、WebTranslateIt等の翻訳サービスからリソースを取り込む際に自動生成してPull Requestに含める等の運用も考えられそうです。

おわりに

生成された型定義ファイルを利用する事でVSCode等のIDE上で以下の様に補完やコンパイル時のエラー検知が可能になりました!

Quipperでは今後もReact Native等の知見を広く発信していきたいと考えています。

ご興味のある方はこちらからどうぞ。