Bill
Bill

Reputation: 5150

React Typescript: Element implicitly has an 'any' type because type has no index signature

When trying to find a key of an object with an item from an array I get an error...

Element implicitly has an 'any' type because type has no index signature

I recreated it in this sandbox https://codesandbox.io/s/affectionate-pasteur-kj5h0

I took a screenshot in case the error does show for any reason here https://i.sstatic.net/PwCbR.png

Upvotes: 1

Views: 2007

Answers (2)

ibtsam
ibtsam

Reputation: 1710

Adding an index signature will let TypeScript know what the type should be. You can do this to get rid of the error

const Translations: {
[key: string]: {
  fname: string;
  lname: string;
  age: string;
  height: string;
  [key: string]: string;
};
} = {
en: {
  fname: "First Name",
  lname: "Last Name",
  age: "Age",
  height: "Height"
},
cn: {
  fname: "名字",
  lname: "姓",
  age: "年龄",
  height: "高度"
}
};

Upvotes: 0

Damian Green
Damian Green

Reputation: 7535

import * as React from "react";
import { render } from "react-dom";
import { useEffect, useState } from "react";

type X = "fname" | "lname" | "age" | "height";
const App: React.FC = props => {
  const [state, setState] = useState<{ array1: X[] }>({ array1: [] });

  const Translations: {
    [key: string]: {
      fname: string;
      lname: string;
      age: string;
      height: string;
    };
  } = {
    en: {
      fname: "First Name",
      lname: "Last Name",
      age: "Age",
      height: "Height"
    },
    cn: {
      fname: "名字",
      lname: "姓",
      age: "年龄",
      height: "高度"
    }
  };

  const object1 = Translations["en"];

  useEffect(() => {
    const array1: X[] = ["fname", "lname", "age", "height"];
    setState({ ...state, array1 });
  }, [state]);

  return (
    <div className="App">
      <ul>
        {state.array1.map((item: X, index: number) => (
          <li key={index}>{object1[item]}</li>
        ))}
      </ul>
      <p>{object1.fname}</p>
    </div>
  );
};

const rootElement = document.getElementById("root");
render(<App />, rootElement);

https://codesandbox.io/s/empty-breeze-kqpqg

Or to make it cleaner and DRY it up you can do : https://codesandbox.io/s/angry-https-rc66o?fontsize=14

Upvotes: 2

Related Questions