Home > Enterprise >  typescript access object dynamically
typescript access object dynamically

Time:11-24

I got this error in typescript

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

when I try to access object property dynamically:

import React, { useState } from "react";

const cities = {
  ny: {
    label: "New York"
  },
  ld: {
    label: "London"
  }
};

export default function App() {
  const [city, setCity] = useState<string>("ny");

  console.log(cities[city].label); //what's wrong here

  return (
    <div className="App">
      hi
    </div>
  );
}

any clue how to get rid of such error?

CodePudding user response:

You say that cities have only two keys when you declare it: "ny" and "ld" but then you allow any city to be a key of your cities element.

Changing:

useState<string>

to

useState<"ny" | "ld">("ny")

should solve your issue.

If you want to allow more city you could also go with this approach:

type City = {
  [key: string]: {
    label: string;
  };
};

const cities: City = {
  ny: {
    label: "New York",
  },
  ld: {
    label: "London",
  },
};

and keep your useState.

Finally you could dynamically generate the possible keys based on your cities const using:

const [city, setCity] = useState<keyof typeof cities>("ny");

CodePudding user response:

You can't use string type to access properties on your object without index type. But if you use useState<keyof typeof cities>("ny"); that will pick up that it's not just a string but specific string in an object("ny" and "ld" in this case).

You can also play around with enum and index types if you need to :)

CodePudding user response:

cities is untyped, and cities.ny too, it's literally "implicitly has an 'any' type". To get rid of this error you should provide type to your variable, for example you can do:

interface City {
    label: string
}

const cities: {[name: string]: City} = {
    ny: {
        label: "New York"
    },
    ld: {
        label: "London"
    }
};

And compiler will know the type of label.

  • Related