Home > Back-end >  Typescript error : Element implicitly has an 'any' type because expression of type 's
Typescript error : Element implicitly has an 'any' type because expression of type 's

Time:06-19

I'm new to typescript and it's a hell trying to make some code works, can someone help me solve this ts error.

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ 'sections.hero': ({ sectionData, key }: props) => Element; }'.   No index signature with a parameter of type 'string' was found on type '{ 'sections.hero': ({ sectionData, key }: props) => Element; }'.

my code :

type sectionDataProps = {
  sectionData: {
    __component: string;
  };
};

// Map Strapi sections to section components
const sectionComponents = {
  'sections.hero': Hero,
};

// Display a section individually
const Section = ({ sectionData }: sectionDataProps) => {
  // Prepare the component
  const SectionComponent = sectionComponents[sectionData.__component];

  if (!SectionComponent) {
    return null;
  }

  // Display the section
  return <SectionComponent data={sectionData} />;
};

// Display the list of sections
const Sections = (props: { sections: [] }) => {
  return (
    <>
      {/* Show the actual sections */}
      {props.sections.map((section) => (
        <Section
          sectionData={section}
          key={`${section.__component}${section.id}`}
        />
      ))}
    </>
  );
};

export default Sections;

CodePudding user response:

In typescript you are not allowed to access properties that may not exist. That means that when have a type like { a: number }, that you may only access the a property. Checking the b property would be a type error because it does not exist.


So you have this type for the key:

__component: string;

And this type for the object that key is expected to be on:

const sectionComponents = {
  'sections.hero': Hero,
};

Which means that only one single string is allowed for this operation:

sectionComponents[sectionData.__component]

And that string is 'sections.hero' any other string will not be allowed.

You can fix this a few ways.


First, you could change the type of the __component property to be:

type sectionDataProps = {
  sectionData: {
    __component: keyof typeof sectionComponents;
  };
};

Now any string is not a valid value. The strings must be keys of the sectionComponents object.

And the rest of you code works without modification. See Playground


If you didn't want to change the props types, you have to change the logic of your function to make sure that you do not access a property that may not exist.

// Display a section individually
const Section = ({ sectionData }: sectionDataProps) => {
  // Prepare the component
  if (sectionData.__component in sectionComponents) {
      const key = sectionData.__component as keyof typeof sectionComponents
      const SectionComponent = sectionComponents[key];
      return <SectionComponent data={sectionData} />;
  }

  return null
};

Here we use an in check to see if a property exists on that object. Then it should be be safe to manually cast that to keyof typeof sectionComponents to let typescript know that we are certifying this operation as safe.

See playground

  • Related