Skip to content

Instantly share code, notes, and snippets.

@NileDaley
Created May 14, 2020 10:55
Show Gist options
  • Select an option

  • Save NileDaley/344868847086ea50d2c66533c5bf3b7f to your computer and use it in GitHub Desktop.

Select an option

Save NileDaley/344868847086ea50d2c66533c5bf3b7f to your computer and use it in GitHub Desktop.
Adds type safety to i18n.t() function based on the keys of the "en" locale file
import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'
import * as locales from '../locales/index'
import * as momentConfig from './moment'
const resources = locales;
i18n.use(LanguageDetector) // Detect the language from the ?lang param
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources,
// lng: "en",
fallbackLng: 'en',
keySeparator: false, // we do not use keys in form messages.welcome
interpolation: {
escapeValue: false, // react already safes from xss
},
detection: {
order: ['querystring'],
lookupQuerystring: 'lang',
caches: [], // Don't store the language anywhere
},
returnEmptyString: false, // Treat empty strings as missing translations
})
.then(() => {
momentConfig.setLocaleFromLanguageCode(i18n.language);
});
export default i18n;
type TranslationKey = keyof typeof locales.en.translation;
declare module 'i18next' {
// Overload the TFunction interface from 'i18next' so that the key parameter only accepts keys defined in en.json
export interface TFunction {
<TResult extends TFunctionResult = string, TInterpolationMap extends object = StringMap>(
key: TranslationKey | TranslationKey[],
options?: TOptions<TInterpolationMap> | string
): TResult;
<TResult extends TFunctionResult = string, TInterpolationMap extends object = StringMap>(
key: TranslationKey | TranslationKey[],
defaultValue?: string,
options?: TOptions<TInterpolationMap> | string
): TResult;
}
}
@NileDaley
Copy link
Author

The real magic is happening here:

    key: TranslationKey | TranslationKey[]

The original type definitions specify string | string[], but this gives us no type safety or auto-completion, whereas TranslationKey | TranslationKey[] tells TypeScript that that value can only be one of the keys of the english locale file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment