Closed2
i18nextのキーを型づけしたい
Template string typesでやってみた
import { useTranslation as useI18NextTranslation } from 'react-i18next';
// ローカライズデータのJSON
import srcLang from '../locales/en';
// JSONからキーを再帰的に抽出。ネストされる度に"."で連結
type KeyPath<T> = keyof {
[P in keyof T & string as T[P] extends string
? P
: KeyPath<T[P]> extends string
? `${P}.${KeyPath<T[P]>}`
: never]: T[P];
};
// 上とほぼ同じことをやるけど、トップレベルのキーは名前空間として":"で連結する必要があるので..
type KeyPathWithNameSpace<T> = keyof {
[P in keyof T & string as T[P] extends string
? P
: KeyPath<T[P]> extends string
? `${P}:${KeyPath<T[P]>}`
: never]: T[P];
};
// 最終結果 => 例: "common:aaa.bbv.ccc | page1:eee.fff | page2:gg.ee"
type LocalizationKey = KeyPathWithNameSpace<typeof srcLang>;
// react-i18nextのラッパー。上で作成した LocalizationKey のみを受け付ける
export function useTranslation() {
const nameSpaces = Object.keys(srcLang);
const { t, ...rest } = useI18NextTranslation(nameSpaces);
const typedT = (key: LocalizationKey, defaultValue?: Parameters<typeof t>[1], options?: Parameters<typeof t>[2]) =>
t(key, defaultValue, options);
return {
t: typedT,
...rest
};
}
もっとよいやり型あるかなー 🤔
別の方法を教えてもらいました
こちらの方がシンプルでよいかもですね😸
このスクラップは2023/02/08にクローズされました