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.