Nevermore
Nevermore

Reputation: 1743

Phpstorm warning string is not assignable to parameter type

I have language.js file like this:

if (localStorage.getItem('lang') === 'en') {
   const LANGCONVERT = {
       "accept": "Accept",
       "accept_invitation": "Accept Invitation"
   }
} else {
   const LANGCONVERT = {
       "accept": "Aceptar",
       "accept_invitation": "Aceptar la invitacion"
   }
}

And i call this script from another scripts. And use like:

console.log(LANGCONVERT.accept);

it works but phpstorm shows a warning:

Unresolved variable or type LANGCONVERT

Argument type string | string is not assignable to parameter type

Checks JavaScript called function arguments , return values , assigned expressions to be of correct type. The validation works in JavaScript, html or jsp files.

Upvotes: 0

Views: 425

Answers (2)

Iulian Cravet
Iulian Cravet

Reputation: 389

I would use a slightly different approach. The way you are trying to use constants is limited to the block scope used in the conditionals.

Why not put all the language-related strings into a module or separate files. something like translation.en.js and translation.es.js Put the const inside those. Load only one file depending on your localStorage variable.

Get the lang variable

let lang = localStorage.getItem('lang') 

If you can import modules (use a transpiler for compatibility)

import {TRANSLATIONS} from `path/to/translation.${lang}.js` 

If not then go old school

let languageFile=document.createElement('script')
     languageFile.setAttribute("type","text/javascript")
     languageFile.setAttribute("src", `path/to/translation.${lang}.js`)
     document.body.appendChild(languageFile)

And then use it like this:

    const LANGCONVERT = {
       accept: TRANSLATIONS['accept'],
       accept_invitation: TRANSLATIONS['accept_invitation']
   }

or use destructuring for shorter notation (again only if with a transpiler)

   let {accept, accept_invitation} = TRANSLATIONS
   const LANGCONVERT = {accept, accept_invitation}

language file example

// make sure to export the const for module usage
const TRANSLATIONS = {
    accept: 'Accept'
    accept_invitation: 'Accept Invitation'
}

you get the idea. And keep in mind, let, const, this are all bound to the parent block scope, you can't really use them outside of that. To overcome that use modules if you can and if not make sure you declare them in the global context.

Hope I gave you at least some useful hints.

Upvotes: 0

Barmar
Barmar

Reputation: 780929

Variables declared with let or const are block-scoped. You need to declare the variable outside the if statement and then assign it in the if.

let LANGCONVERT;
if (localStorage.getItem('lang') === 'en') {
   LANGCONVERT = {
       "accept": "Accept",
       "accept_invitation": "Accept Invitation"
   }
} else {
   LANGCONVERT = {
       "accept": "Aceptar",
       "accept_invitation": "Aceptar la invitacion"
   }
}

or you could initialize it using a conditional expression:

const LANGCONVERT = localStorage.getItem('lang') === 'en' ? 
    {
       "accept": "Accept",
       "accept_invitation": "Accept Invitation"
    } : {
       "accept": "Aceptar",
       "accept_invitation": "Aceptar la invitacion"
    };

Upvotes: 1

Related Questions