Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to solve "expression of type 'string' can't be used to index type"

I try to migrate a webseite from React to Next.js, but struggeling to implement i18n for SSR-pages. At the moment I try to follow this tutorial here: https://localizely.com/blog/nextjs-i18n-tutorial/

I’ve already created an lang-folder and put some json-files in there. Here is the content of de.json:

{
    "demo": "Startseite (de)",
    "eventlist":"Event-Liste",
    "menu": {
        "home": "Startseite",
        "events": "Events",
        "nearby" : "In deiner Nähe",
        "worthknowing": "Gut zu wissen",
        "about": "Ăśber uns"
    }
}

I’ve also followed the tutorial to adapt the _app.tsx:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

...
import { useRouter } from 'next/router'
import { IntlProvider } from 'react-intl'
import de from '../lang/de.json'
import en from '../lang/en.json'
import fr from '../lang/fr.json'
import it from '../lang/it.json'
...
const messages = {
  de: de,
  en: en,
  fr: fr,
  it: it,
}
...
function App({ Component, pageProps }: AppProps) {
  let { locale } = useRouter()
  return (
    <IntlProvider locale={locale} messages={messages[locale]}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </IntlProvider>
  )
}

export default App

Unfortunately there is a problem to set the messages-prop of the IntlProvider:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type

I can see, what the problem ist, whenI inspect the "messages"-object:

const messages: {
    de: {
        demo: string;
        eventlist: string;
        menu: {
            home: string;
            events: string;
            nearby: string;
            worthknowing: string;
            about: string;
        };
    };
...

As this is the first time, I use TypeScript, i’m some kind of lost to figure out how to solve this situation.

I can think of 3 different solutions:
a) type casting "locale" at the point, where I assign thes "messages"-Prop
b) type casting "locale" at definition time
c) somehow use Strings as object keys in "messages"

What is the best way, to work this out?

>Solution :

The error message is indicating that the type of the locale variable is not matching the keys of the messages object.
try to add typeof like so:


let { locale } = useRouter()
const messages = {
  de: de,
  en: en,
  fr: fr,
  it: it,
}
const localeKey = locale as keyof typeof messages //this should help
return (
  <IntlProvider locale={locale} messages={messages[localeKey]}>
    <Layout>
      <Component {...pageProps} />
    </Layout>
  </IntlProvider>
)

but I would advise to look for a better solution for managing language support.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading