i18next documentation
🏠 i18next🌐 localization as a service🎓 i18next crash course💾 GitHub Repository
  • Introduction
  • Overview
    • Getting started
    • Comparison to others
    • API
    • Configuration Options
    • Supported Frameworks
    • Plugins and Utils
    • For Enterprises
    • First setup help
    • TypeScript
  • Translation Function
    • Essentials
    • Interpolation
    • Formatting
    • Plurals
    • Nesting
    • Context
    • Objects and Arrays
  • Principles
    • Best Practices
    • Translation Resolution
    • Namespaces
    • Fallback
    • Plugins
  • How to
    • Add or Load Translations
    • Extracting translations
    • Caching
    • Backend Fallback
    • FAQ
  • Misc
    • JSON Format
    • Creating own Plugins
    • Migration Guide
    • The history of i18next
    • Testimonials
  • 🌐localization as a service
  • 🎓i18next crash course
  • 💾GitHub Repository
Powered by GitBook
On this page
  • Create a declaration file
  • Some examples
  • Custom Type Options
  • Troubleshooting
  • Intellisense not working
  • Out of memory (OOM) errors
  • Not working interpolation values
  • Type 'HTMLAttributes<T>' is not assignable to type...
  • Type error - template literal
  • Type error - excessively deep and possibly infinite
  • Tagged Template Literal (react-i18next only)
  • Customize t function return when returnObjects is set to true but CustomTypeOptions.resources is not used (>= v23)
  • Troubleshooting (< 23)
  • Slow compilation time
  • Argument of type 'DefaultTFuncReturn' is not assignable to parameter of type xyz
  1. Overview

TypeScript

Last updated 5 months ago

i18next has embedded type definitions. If you want to enhance IDE Experience and prevent errors (such as type coercion), you should follow the instructions below in order to get the t function fully-type safe (keys and return type).

This is an optional feature and may affect the compilation time depending on your project's size. If you opt not to leverage the type enhancements suggested here, you can ignore this section.

Make sure your tsconfig compilerOptions has the flag or the set to true. The newest i18next versions only support TypeScript v5. Older TypeScript versions are not supported any longer with i18next > v23. To use it with TypeScript v4, use i18next@22.5.1.

If your project spans multiple i18next instances with different translation resources, you probably can't use type-safe translations.

you'll find a simple guide on how to best use TypeScript for i18next. Discover how to unleash the full potential of i18next in your TypeScript applications by mastering type-safe translations, ensuring accurate localization and eliminating runtime errors.

Create a declaration file

// import the original type declarations
import "i18next";
// import all namespaces (for the default language, only)
import ns1 from "locales/en/ns1.json";
import ns2 from "locales/en/ns2.json";

declare module "i18next" {
  // Extend CustomTypeOptions
  interface CustomTypeOptions {
    // custom namespace type, if you changed it
    defaultNS: "ns1";
    // custom resources type
    resources: {
      ns1: typeof ns1;
      ns2: typeof ns2;
    };
    // other
  }
}

Or, if you want to include all namespaces at once, you can use our preferred approach:

i18n.ts

export const defaultNS = "ns1";
export const resources = {
  en: {
    ns1,
    ns2,
  },
} as const;

i18n.use(initReactI18next).init({
  lng: "en",
  ns: ["ns1", "ns2"],
  defaultNS,
  resources,
});

i18next.d.ts

import { resources, defaultNS } from "./i18n";

declare module "i18next" {
  interface CustomTypeOptions {
    defaultNS: typeof defaultNS;
    resources: typeof resources["en"];
  }
}

We recommend creating a @types directory under src or above it and placing all your type declarations there. E.g.: @types/i18next.d.ts

Some examples

Custom Type Options

We provide a few options that can improve TypeScript for i18next. All options come with default values, and if you want to change them, you just need to add them under CustomTypeOptions interface in your i18next type declaration file (i18next.d.ts).

option
default
description

defaultNS

'translation'

Default namespace. This is more practical in React applications, so when you call useTranslation() hooks without passing the namespace, it will infer the types for the translation namespace.

resources

object

Resources to initialize with. This is the most important option that is used to infer the appropriate keys and return types.

fallbackNS

false

keySeparator

'.'

Char to separate keys.

nsSeparator

':'

Char to split namespace from key

pluralSeparator

'_'

Char to split namespace from key

contextSeparator

'_'

Char to split context from key

returnNull

true

Allows null values as valid translation.

returnObjects

false

Allows objects as valid translation result

compatibilityJSON

'v4'

allowObjectInHTMLChildren

false

Flag that allows HTML elements to receive objects. This is only useful for React applications where you pass objects to HTML elements so they can be replaced to their respective interpolation values (mostly with Trans component)

interpolationPrefix

'{{'

Prefix for interpolation

interpolationSuffix

'}}'

Suffix for interpolation

strictKeyChecks

false

Flag that enables strict key checking even if a defaultValue has been provided. This ensures all calls of t function don't accidentally use implicitly missing keys.

Troubleshooting

Intellisense not working

Try to update the used TypeScript version (>= v5 is recommended).

Out of memory (OOM) errors

Running typechecking with key validation might result in OOM errors. This can be facilitated by additional factors like:

  • large codebase with a lot of namespace with hundreds of keys

  • running typechecking alongside other tools like ESLint combined with typescript-eslint

When having this kind of error consider to:

  • If you are on a large codebase consider split the typecheck / lint process in separate tasks

  • Split the code in multiple packages (monorepo)

  • Use Node --max-old-space-size option to increase Node memory

    E.g.:

    export NODE_OPTIONS=\"--max_old_space_size=10240\" && tsc

If you report a OOM error, please provide an easy way to reproduce the issue using:

  • online sandbox

  • example repository

Not working interpolation values

Type 'HTMLAttributes<T>' is not assignable to type...

Type error - template literal

If you face this issue:

Argument of type 'string' is not assignable to parameter of type ...

When using the following approach (template literal with an expression):

// with i18next
i18next.t(`${expression}.title`);

// with react-i18next
const { t } = useTranslation();
t(`${expression}.title`);

Or:

// with react-i18next
const { t } = useTranslation(`${ns}Default`);

TypeScript will lose the literal value, and it will infer the key as string, which will cause to throw the error above. In this case, you will need to assert the template string as const, like this:

// with i18next
i18next.t(`${expression}.title` as const);

// with react-i18next
const { t } = useTranslation();
t(`${expression}.title` as const);

For now, this is the only possible workaround. This is a TypeScript limitation that will be address at some point in the future.

Type error - excessively deep and possibly infinite

If you face this issue whenever calling the t function:

TS2589: Type instantiation is excessively deep and possibly infinite.

Tagged Template Literal (react-i18next only)

If you are using the tagged template literal syntax for the t function, like this:

t`key1.key2`;

Customize t function return when returnObjects is set to true but CustomTypeOptions.resources is not used (>= v23)

When no resources are defined inside CustomTypeOptions and returnObject options is set to true t function returns a $SpecialObject type:

type $SpecialObject = object | Array<string | object>; 

Due to his anatomy it can be easily casted to a better defined type as you can see from the following examples:

Example with object

const tResult = t('myTypeKey', { returnObjects: true }) as { title: string, text: string };
expectTypeOf(tResult).toEqualTypeOf<{ title: string; text: string }>();

Example with array

const tResult = t('myTypeKey', { returnObjects: true }) as Array<string>;
expectTypeOf(tResult).toEqualTypeOf<Array<string>>();

Example without casting using type parameters

type MyCustomReturn = { title:string; text: string };
const tResult = t<string, { returnObjects: true }, MyCustomReturn>('myKey', { returnObjects: true });
expectTypeOf(tResult).toEqualTypeOf<MyCustomReturn>();

Troubleshooting (< 23)

The following problems should not be present since v23.0.0

Slow compilation time

In order to fully type the t function, we recursively map all nested keys from your primary locale files or objects. Depending on the number of keys your project have, the compilation time could be noticeably affected. If this is negatively influencing your productivity, this feature might not be the best choice for you. If needed, you can always open an issue on Github to get some help from us.

Argument of type 'DefaultTFuncReturn' is not assignable to parameter of type xyz

// i18next.d.ts
import 'i18next';

declare module 'i18next' {
  interface CustomTypeOptions {
    returnNull: false;
    ...
  }
}
i18next.init({
  returnNull: false,
  // ...
});

TypeScript definitions for i18next can be extended by using and . So the first step is creating a declaration file (i18next.d.ts), for example:

(from simple i18next only to react-i18next prod ready)

Fallback namespace. string or array of namespaces to lookup key if not found in given namespace. .

Only 'v4' is supported. Enable plurals keys support. See .

t function infers interpolation values, but it'll only work if the translation files (resources) are placed in a ts file and using as const (like ) or an (can be generated like ), JSON files don't support as const to convert objects to be type literals (yet).

This happens when is disabled. Setting skipLibCheck in tsconfig to true will remove this issue.

That probably means you did not set up your type declaration correctly, so review your configuration or check for some similar cases that may help you. If needed, you can always open an issue on Github to get some help from us.

The keys and return type inference will not work, because does not accept generic types yet. You can use Tagged Template Literal syntax, but it will accept any string as argument.

t function can return null, this behaviour is , if you want to change it, set returnNull type to false.

I also recommend updating your to behave accordantly:

Type Augmentation
Merging Interfaces
various examples
react-i18next
next-i18next
next-13-app-dir-i18next-example-ts
react-i18next-example-app-ts
this
interface in a d.ts file
this
skipLibCheck
here
TemplateStringsArray
set by default
i18next configuration
See NS fallback docs
Plurals docs
strict
strictNullChecks
Here