Error: Unable to initialize i18next as a function

For my current project, I am utilizing TypeScript and i18next for internalization.

TypeScript version: 2.1.4

i18next version: 2.3.4

@types/i18next version: 2.3.35

In the specific file:

import * as i18next from 'i18next';

i18next.init({
    lng: 'en',
    resources: {
        en: {
            translation: {
                "key": "hello world"
            }
        }
    }
}, (err, t) => {
    // Initialization complete!
    const hw = i18next.t('key'); // hw = 'hello world'
});

However, when inspecting in the browser, an error message is displayed:

Uncaught TypeError: i18next.init is not a function

If I log the i18next object, it displays like this:

https://i.sstatic.net/FfsVZ.png

And in the console, calling i18n.default.init works fine.

When importing as such:

import i18next from 'i18next';

Visual Studio Code will raise a complaint: https://i.sstatic.net/3BXCa.png

My .tsconfig file looks like this:

{
    "compileOnSave": true,
    "compilerOptions": {
        "removeComments": false,
        "baseUrl": "./src",
        "target": "es6",
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "jsx": "preserve",
        "lib": [
            "es2017",
            "dom"
        ],
        "typeRoots": [
            "./node_modules/@types"
        ],
        "types": [
            "node",
            "poly2tri",
            "three",
            "i18next"
        ]
    }
}

Unfortunately, my webpack.config.js file is too lengthy to include here.

I'm curious if there is any connection to this document: http://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-class-d-ts.html

/*~ Note that ES6 modules cannot directly export class objects.
 *~ This file should be imported using the CommonJS-style:
 *~   import x = require('someLibrary');
 *~
 *~ Refer to the documentation to understand common
 *~ workarounds for this limitation of ES6 modules.
 */

Answer №1

Your issue is directly linked to

https://github.com/Microsoft/TypeScript/issues/7398

https://github.com/Microsoft/TypeScript/issues/8687

https://github.com/systemjs/systemjs/issues/1587

The discrepancy lies in the module resolution syntax between TypeScript and Babel/NodeJS.

In Babel/NodeJS (latest draft), CommonJS modules are imported using this syntax:

import i18n from 'i18next'

Essentially, the CommonJS module is transferred to the default export of an ES6 module.

On the other hand, TypeScript doesn't follow this approach:

import * as i18n from 'i18next'

Consequently, when compiled by tsc to es6, this import statement remains unchanged, resulting in a misinterpretation by Babel.

To address this issue, please advocate for it on the mentioned threads to garner more attention from the relevant teams.

This problem should be prioritized and fixed promptly.

One temporary solution is to compile your code down to es5 through tsc instead.

Answer №2

Summary

If you are using i18next version 17.0.0+, make sure to import it like this:

import { default as i18n } from 'i18next';

To make it compatible with jest, set "esModuleInterop": true in your tsconfig.js.

You may need these additional module configurations in your tsconfig.js:

"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"module": "es6",
"moduleResolution": "node",
"target": "es6",

Explanation

In version 17.0.0, i18next made changes to how the module is exported:

  • The main file no longer has named exports, which improves compatibility with commonjs scenarios (node.js) - no longer requiring const i18next = require('i18next').default;
  • This change means you can't do import { changeLanguage } from 'i18next'; changeLanguage('de'); anymore; instead, import i18next from 'i18next'; and then use i18next.changeLanguage('de');

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Express encounters difficulty in processing Chunked Post Data

I am currently retrieving data from a Campbell Scientific data logger. This data is being posted to an application that is coded in Typescript using Express and BodyParser. The request successfully reaches the app (as I'm able to debug it), however, t ...

Deactivate user session in LoopBack 4 API

Can anyone provide a clear example of an API endpoint for logging out that allows for deleting the token stored during login instead of relying on the web browser? It seems there is no documentation available on how LoopBack generates a default user when ...

Unable to locate dependencies while testing the react package locally

Recently, I came across this npm package designed for React using Typescript. To debug it locally, I initiated npm link in a new React project but encountered an error: https://i.sstatic.net/nObH6.png I suspect it may not be reading the packages correct ...

Various dateInput formats supported by mat-datepicker

I'm facing an issue while configuring two mat-datepickers with different date formats - "MM/YYYY" and "DD/MM/YYYY". I attempted to set the format for MM/YYYY in one module and the format for DD/MM/YYYY in the app module. Here is my first code snippet ...

What is the best way to asynchronously refresh Angular 2 (or 4) PrimeNg Charts?

Issue: How can PrimeNg Charts be updated asynchronously? Situation: I have a dropdown menu that should trigger a chart refresh based on the user's selection. I believed I had the solution figured out, understanding Angular change detection and reali ...

Universal Parameter Typing in Functions

I'm grappling with a concept that seems obvious to me, yet is disallowed by Typescript when all strict flags are enabled (presumably for valid reasons). Let me illustrate: We all understand the following: export interface Basic { value: "foo&q ...

Encountering difficulties importing in Typescript and ts-node node scripts, regardless of configuration or package type

I am facing a challenge with my React Typescript project where multiple files share a similar structure but have differences at certain points. To avoid manually copying and pasting files and making changes, I decided to create a Node script that automates ...

Tips on preventing image previews from consuming too much text data while updating a database in Angular 12 using Material UI for image uploads within a FormGroup object

Currently working with Angular 12 and Angular Material for image uploads with preview. I have a formgroup object below, but I'm running into issues with the 197kb image preview text being inserted into the database. Despite trying setValue/patchValue/ ...

You are unable to link to <custom directive selector> because it is not recognized as a valid property of 'div'

I am currently working on a project in StackBlitz, and you can find the link here: https://stackblitz.com/edit/angular-fxfo3f?file=src/directives/smooth-height.directive.ts I encountered an issue: Error in src/components/parent/parent.component.html (2:6) ...

RxJS: the art of triggering and handling errors

This is more of a syntax question rather than a bug I'm facing. The process is straightforward: Send an HTTP request that returns a boolean value If the boolean is true, proceed If the boolean is false, log a warning and stop the flow. To handle ...

Limit pasted content in an Angular contenteditable div

Is there a way to limit the input in a contenteditable div? I am developing my own WYSIWYG editor and want to prevent users from pasting content from external websites and copying styles. I want to achieve the same effect as if the content was pasted into ...

the process of altering properties in vue js

After running my Vue file, I encountered the following console error. As someone new to Vue programming, I'm attempting to utilize a Syncfusion UI component to display a grid. Prop being mutated: "hierarchyPrintMode" I am unsure where to add the comp ...

The data that has been retrieved is not currently displayed within the Vue table

I'm currently exploring js/vue and I'm attempting to retrieve data from an API. There's a field where the value is used to fetch data from the API based on that keyword. When I check the console log, I can see that the data is being received ...

Navigating any object array in TypeScript and retrieving its properties

Consider the following JSON data object: var dataObjects = [ { "Name": "Date & Time", "Type": "Date", "Value": "2019-12-11" }, { "Name": "Activity", "Type": "String", ...

Exploring unit tests: Customizing an NGRX selector generated by entityAdapter.getSelectors()

Let's imagine a scenario where our application includes a books page. We are utilizing the following technologies: Angular, NGRX, jest. To provide some context, here are a few lines of code: The interfaces for the state of the books page: export int ...

Caution: The file path in node_modules/ngx-translate-multi-http-loader/dist/multi-http-loader.js relies on the 'deepmerge' dependency

My micro-frontend angular project is using mfe (module federation). I recently updated it from angular 13 to 14 and encountered some warnings such as: node_modules\ngx-translate-multi-http-loader\dist\multi-http-loader.js depends on ' ...

The type 'string' cannot be utilized to index type

Apologies for adding yet another question of this nature, but despite finding similar ones, I am unable to apply their solutions to my specific case. Could someone please assist me in resolving this TypeScript error? The element implicitly has an 'an ...

The most efficient and hygienic method for retrieving a value based on an observable

Looking at the structure of my code, I see that there are numerous Observables and ReplaySubjects. When trying to extract a value from one of these observables in the HTML template, what would be the most effective approach? In certain situations, parame ...

Retrieve the service variable in the routing file

How do I access the service variable in my routing file? I created a UserService with a variable named user and I need to use that variable in my routing file. Here is the approach I tried, but it didn't work: In the routing file, I attempted: cons ...

Top method for changing Enum to Set in TypeScript

Take a look at the enum below: enum Animes { OnePiece = 'One Piece', Naruto = 'Naruto', Bleach = 'Bleach' } How can we efficiently transform this enum into a Set? ...