---
title: 型で頑張るプロダクト国際化
tags: 
author: [shzawa](https://www.docswell.com/user/shzawa)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/4JZLPW8RE3.jpg?width=480
description: TSKaigi 2026 登壇資料
published: May 22, 26
canonical: https://www.docswell.com/s/shzawa/Z8NMV2-2026-05-22-153117
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/4JZLPW8RE3.jpg)

型で頑張るプロダクト国際化
© Techtouch, Inc.
TSKaigi 2026
#TSKaigi #tskaigi_leverages


# Page. 2

![Page Image](https://bcdn.docswell.com/page/YE6WMGP1EV.jpg)

トーク概要
[前提]
Reactベースのフロントエンドアプリケーションでの国際化対応
国際化対応に用いられるフレームワークのうち、i18next/react-i18next を対象
[話すこと]
1. プロダクトの国際化を進める上でぶつかった課題を型の仕組みで解消しようとした話
2. react-i18next の最新の型機能の紹介
2 / 24


# Page. 3

![Page Image](https://bcdn.docswell.com/page/GE5MZVKLE4.jpg)

発表者紹介
名前: Shotaro Ozawa
Twitter (現X): @shzawa
テックタッチ株式会社でフロントエンドエンジニアをやってます
DAPサービスの開発に携わってます
大阪出身です
趣味は野球観戦です
今シーズンからDAZNの年間契約をし始めました
3 / 24


# Page. 4

![Page Image](https://bcdn.docswell.com/page/9729R3W3JR.jpg)

本編に入ります
4 / 24


# Page. 5

![Page Image](https://bcdn.docswell.com/page/DJY4D1L87M.jpg)

課題発見までの経緯
プロダクトがある程度成熟している状態で、国際化対応 (日英の二言語) プロジェクト
がプロダクトロードマップに載った。
一応プロダクト開発初期から i18next/react-i18next が導入されてはいた。
lng: [&#039;ja&#039;] 固定
辞書データの整備はおざなり。割れ窓状態
プロジェクトを進めるうちに、そんな状態ならではの課題が見つかった。
5 / 24


# Page. 6

![Page Image](https://bcdn.docswell.com/page/V7NY6249E8.jpg)

開発中の課題
1. t 関数のラップ (= i18n化) が漏れている文字列の検出問題
a. 日本語テキストを定数化しているパターン、など
2. 辞書データ登録漏れ問題
a. 未登録な翻訳キーがあってもビルドできてしまう (型チェックが通ってしまう)
6 / 24


# Page. 7

![Page Image](https://bcdn.docswell.com/page/YJ9PL1Q373.jpg)

開発中の課題
1. t 関数のラップ (= i18n化) が漏れている文字列の検出問題
a. 日本語テキストを定数化しているパターン、など
2. 辞書データ登録漏れ問題
a. 未登録な翻訳キーがあってもビルドできてしまう (型チェックが通ってしまう)
今回は時間の都合により課題2にフォーカスしてお話しします。
7 / 24


# Page. 8

![Page Image](https://bcdn.docswell.com/page/GJ8DX4GLJD.jpg)

開発中の課題
2. 辞書データ登録漏れ問題
a. 未登録な翻訳キーがあってもビルドできてしまう (型チェックが通ってしまう)
react-i18next の場合...
TypeScript用の設定ファイル i18next.d.ts を用意することで検出機能を有効化できる
らしい
strictKeyChecks オプションの有効化
8 / 24


# Page. 9

![Page Image](https://bcdn.docswell.com/page/LJLM86GQER.jpg)

strictKeyChecks
オプション
9 / 24


# Page. 10

![Page Image](https://bcdn.docswell.com/page/47MY65LK7W.jpg)

strictKeyChecks
オプション
このオプションを有効にすることで、辞書データにあるすべてのキーを取りうる
Union 型が合成され、 t 関数の引数型として注入されます。
10 / 24


# Page. 11

![Page Image](https://bcdn.docswell.com/page/P7R9P3K6E9.jpg)

strictKeyChecks
設定方法↓
オプション
// i18next.d.ts
import &#039;i18next&#039;
import type jaJson from &#039;./locales/ja.json&#039;
import type enJson from &#039;./locales/en.json&#039;
// パイプラインで繋ぐことで、キーが全ての辞書データに存在するかがチェックできます。
type Translation = typeof jaJson | typeof enJson
declare module &#039;i18next&#039; {
interface CustomTypeOptions {
defaultNS: &#039;translation&#039;
resources: { translation: Translation }
strictKeyChecks: true
}
}
※ tsconfig.json で `compilerOptions.resolveJsonModule: true` を指定する必要があります。
11 / 24


# Page. 12

![Page Image](https://bcdn.docswell.com/page/PJXQ34LD7X.jpg)

strictKeyChecks
オプションを適用してみた
12 / 24


# Page. 13

![Page Image](https://bcdn.docswell.com/page/3JK9YZLDJD.jpg)

strictKeyChecks
オプションを適用してみた
辞書データが2,000件程度のプロダクトに適用したところ、実際に合成された型が
エディター上から確認できました (情報量多い・・・)
13 / 24


# Page. 14

![Page Image](https://bcdn.docswell.com/page/LE3W9D3PE5.jpg)

strictKeyChecks
オプションを適用してみた：終わり
また、適用する前と後とで tsc の実行時間が大きく変わらないことも確認できました。
プロジェクトが完了してしばらくした後、 strictKeyChecks オプション を置き換える
目的で作られた新機能 &quot;Selector API&quot; がリリースされたことを知り、調査を進めてみま
した。
キーから翻訳テキストを辿るために一々 grep しないといけない
14 / 24


# Page. 15

![Page Image](https://bcdn.docswell.com/page/8EDKGP437G.jpg)

Selector API
15 / 24


# Page. 16

![Page Image](https://bcdn.docswell.com/page/V7PK3NMPJ8.jpg)

Selector API
この機能の開発にあたって t 関数のAPIレベルで設計が見直されており、
キーの指定方法が「既存のキー文字列を与える」形から
「オブジェクトプロパティを参照するコールバック関数を与える」形に置き換えられま
す。
// before
t(&#039;key&#039;)
// after
t($ =&gt; $.key)
16 / 24


# Page. 17

![Page Image](https://bcdn.docswell.com/page/2JVV4K9VJQ.jpg)

Selector API
設定方法↓
// i18next.d.ts
...
declare module &#039;i18next&#039; {
interface CustomTypeOptions {
defaultNS: &#039;translation&#039;
resources: {
translation: Translation
}
enableSelector: true
}
}
※ パフォーマンスに支障をきたす環境では `enableSelector: &#039;optimize&#039;` の指定が推奨されています。(トレー
ドオフ機能あり)
17 / 24


# Page. 18

![Page Image](https://bcdn.docswell.com/page/5EGL1QZ1JL.jpg)

Selector API
翻訳キーの存在判定ロジックは strictKeyChecks 有効時とで以下のように異なります。
before:
i. typeof 翻訳データ を再帰的に走査して文字列 Union 型で結びつける
ii. t(key) の引数の型として Union 型を注入
after:
i. t($ =&gt; $.key) のコールバック引数の型として typeof 翻訳データ を
ほぼそのまま注入
18 / 24


# Page. 19

![Page Image](https://bcdn.docswell.com/page/4JQYDKLN7P.jpg)

Selector API
プロパティアクセサーの形なので、キーから翻訳テキストを辿るのに
エディターの「定義へ移動」機能 が利用できます。 ← これ地味に求めてたやつ
strictKeyChecks 有効時から、型検査のパフォーマンスが最大で約1,700倍も向上す
るようです。
https://github.com/i18next/i18next/pull/2322 より
また、APIに破壊的変更が加わることから、非Selector API環境で構築済みのコードベ
ースのマイグレーション用に codemod が提供されています。
https://www.npmjs.com/package/i18next-selector-codemod
19 / 24


# Page. 20

![Page Image](https://bcdn.docswell.com/page/K74WZPD3E1.jpg)

Selector API 実践編
感触としては良い感じ。
これは今すぐにも Selector API 利用に乗り換えるべきでは
(影響範囲が広くなるから動作確認が大変なのはさておき)
というわけで実際にプロジェクトへの適用を試みたところ…
20 / 24


# Page. 21

![Page Image](https://bcdn.docswell.com/page/LJ1YR9ZZEG.jpg)

Selector API 実践編
キーが未登録かは爆速で判定されるようになったけど、出力されるエラーが
思うてたんと違う...
21 / 24


# Page. 22

![Page Image](https://bcdn.docswell.com/page/GJWG1Q9672.jpg)

Selector API 実践編
こうなった原因は以下の2つでした。
1. キーがほぼすべて日本語文字で並べられている
2. キーがすべてフラット
なので、機能有効化と並行して辞書データの構造見直しも進めていこうと思います。
辞書データ構造の指針について説明されている記事 (自分調べ)
&quot;Translation key naming conventions: 11 best practices for developers&quot; - Ilya Krukowski氏
https://lokalise.com/blog/translation-keys-naming-and-organizing/
&quot;TypeScriptで実現する型安全な多言語化(i18n)設計 - アーキテクチャから運用まで&quot; - 日向 一樹氏
https://zenn.dev/nexx_hinata/articles/38635095faab70#翻訳キー設計のベストプラクティス
22 / 24


# Page. 23

![Page Image](https://bcdn.docswell.com/page/4EZLPW9R73.jpg)

まとめ
辞書データは適切に構造化しておくべし
react-i18next をこれから導入するプロダクトでは Selector API 利用がおすすめ
react-i18next 導入済みのプロダクトには、まずは strictKeyChecks: true 適用が
おすすめ
マイグレーションが可能な状況であれば Selector API 利用がおすすめ
23 / 24


# Page. 24

![Page Image](https://bcdn.docswell.com/page/Y76WMGK17V.jpg)

まとめ
辞書データは適切に構造化しておくべし
react-i18next をこれから導入するプロダクトでは Selector API 利用がおすすめ
react-i18next 導入済みのプロダクトには、まずは strictKeyChecks: true 適用が
おすすめ
マイグレーションが可能な状況であれば Selector API 利用がおすすめ
ご清聴ありがとうございました！
24 / 24


