Home > Blockchain >  Assigning/returning an imported json file to a variable in TypeScript
Assigning/returning an imported json file to a variable in TypeScript

Time:12-26

I have a json file that contains data like this

{
  "login": {
    "email": "Email",
    "firstName": "First name",
    "lastName": "Last name",
    "noAccountYet": "No account yet?",
    "password": "Password",
    "signIn": "Sign in",
    "signInWithApple": "Sign in with Apple",
    "signInWithGoogle": "Sign in with Google"
  },
  "errors": {
    "invalidCredentials": "Invalid credentials",
    "invalidEmail": "Not a valid e-mail address"
  }
}

I want to import it into a helper-functions file and return the entire object from a const or function to be accessed with dot-notation, like this:

// helper-functions.ts
import * as en from '../../src/assets/i18n/en.json';
import * as de from '../../src/assets/i18n/de.json';

export const translationHandle: any = () => {
  if (Cypress.env('LANG') === 'en') {
    return en;
  } else {
    return de;
  }
};


// assigned in a different file
const lang = translationHandle();
// and accessed using dot-notation like  lang.errors.invalidEmail

I'm writing E2E tests with Cypress for a dual-lingual app. And I would like to have access to the correspondent language text file based on the language set in the global environment.

The problem is that the returned value from the const translationHandle above is undefined. Although, running in debug mode shows that lang itself contains a Module, it's only when I try to access it with dot-notation do I get a Cypress error that it's undefined.

I also tried to just do this locally in each file with if-else and assigning the correspondent language object to a const. However, I also get undefined.

The only that worked for me thus far is if I directly access the file as imported, e.g. en.login.lastName.

I am aware that this issue stems from my lack of understanding of how TypeScript works, and so I'm not only asking for answers to this specific issue, but also any resources/explanations that could help me clear my misunderstandings.

CodePudding user response:

You are trying to import a JSON file in your TypeScript code and use it as an object. In order to do this, you will need to use the import statement and type the imported value as an object.

Here is an example of how you could modify your translationHandle function to correctly import and return the JSON data:

import * as en from '../../src/assets/i18n/en.json';
import * as de from '../../src/assets/i18n/de.json';

interface TranslationData {
  login: {
    email: string;
    firstName: string;
    lastName: string;
    noAccountYet: string;
    password: string;
    signIn: string;
    signInWithApple: string;
    signInWithGoogle: string;
  },
  errors: {
    invalidCredentials: string;
    invalidEmail: string;
  }
}

export const translationHandle = (): TranslationData => {
  if (Cypress.env('LANG') === 'en') {
    return en;
  } else {
    return de;
  }
};

In this example, I have defined an interface called TranslationData which represents the shape of the JSON data. I have then used this interface as the return type of the translationHandle function. This will allow TypeScript to properly type the imported JSON data as an object and make it available for you to use with dot notation, like lang.errors.invalidEmail.

CodePudding user response:

The problem was with how I was importing the .json - not really a problem but I just wasn't aware of its functionality. I was doing import * as en from ./file/name/ which was adding a default root field in the object. That's because import * imports the namespace, which contains all the other exports. Changing the import statement to import en from resolved the issue. Alternatively, I could've just added the default field name to the dot-notation sequence: en.login.signUp => en.default.login.signUp.

  • Related