I have a span in my JSX in which I want to render a proper icon based on the dynamic props value
<span>{IconToProductMap(value)}</span>
This is how this function looks like
const IconToProductMap = (value: string) => {
if (value === 'sampleValue') {
return <Icon type={IconType.card} />
}
if (value === 'sampleValue2') {
return <Icon type={IconType.card2} />
}
return <Icon type={IconType.card3} />
}
This solution is really bad and I'd like to be able to dynamically assign the value so that I can render the icon like this
<span>{IconToProductMap[value]}</span>
To achieve that I've created the mapper object
const mapper = {
possiblePropsValue1: IconType.card,
possiblePropsValue2: IconType.bag,
possiblePropsValue3: IconType.arrow_left,
}
and used it like so:
<span>{mapper[value]}</span>
The problem is that TS throws
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ possiblePropsValue1: IconType; possiblePropsValue2: IconType; possiblePropsValue3: IconType; }'. No index signature with a parameter of type 'string' was found on type '{ possiblePropsValue1: IconType; possiblePropsValue2: IconType; possiblePropsValue3: IconType; }'
I'd be really glad if someone could explain how to properly fix that. Thanks in advance
CodePudding user response:
You should define mapper
with a proper type
const mapper: Record<string, JSX.Element> = {
possiblePropsValue1: IconType.card,
possiblePropsValue2: IconType.bag,
possiblePropsValue3: IconType.arrow_left,
}
Record<key,value>
receives key
as string, value
as JSX.Element
which is from your IconType
returned value.
CodePudding user response:
You can use an enum to simplify string parameters & better manage the icon types. You can store the strings (sampleValue
) in the enum.
enum IconType {
card = "card",
bag = "bag",
arrow_left = "arrow_left"
}
interface IconProps {
iconType: IconType;
}
const Icon = (props: IconProps) => {
const { iconType } = props;
return <div>{iconType}</div>; // just for demonstration
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Icon iconType={IconType.bag} />
</div>
);
}