I’m quite new to TS and would like to understand why I get a type error in the following code (simplified):
"use client";
import { ArrowDownWideNarrow, Settings } from "lucide-react";
interface LinkItemProps {
name: string;
}
const iconMap = {
Categories: <ArrowDownWideNarrow />,
Admin: <Settings />,
};
export const LinkItem = ({ name }: LinkItemProps) => {
<div>
{iconMap[name]}
</div>
}
The error is in the `{iconMap[name]}:
"Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ Categories: Element; Admin: Element; }'.
No index signature with a parameter of type 'string' was found on type '{ Categories: Element; Admin: Element; }'."
The parent element has the following:
const LINKS = [
{
href: "/admin",
name: "Admin",
id: "admin",
},
{
href: "/categories",
name: "Categories",
id: "categories",
},
];
export const Sidebar = async () => {
return (
<div>
{LINKS.map((link) => (
<div key={link.href}>
<LinkItem href={link.href} id={link.id} name={link.name} />
</div>
))}
</div>
)
}
>Solution :
No index signature with a parameter of type ‘string’ was found on type ‘{ Categories: Element; Admin: Element; }’."
The string type is too wide, you could be more specific on the name prop type so it properly inherits the fields based on the iconMap object.
interface LinkItemProps {
name: keyof typeof iconMap;
}
or a manual, strictly typed approach:
interface LinkItemProps {
name: 'Categories' | 'Admin';
}