如何将图标作为道具传递给打字稿

loo*_*ool 6 javascript typescript reactjs next.js

我是打字稿新手,开始了一个简单的项目。我有一个由多个 sidebarNavigationItem 组件组成的侧边栏组件。每个侧边栏项目都有一个图标和标题,如下所示。

侧边栏.tsx

import SidevarNavigationItem from "./SidevarNavigationItem"
import { HomeIcon } from "@heroicons/react/24/solid"
import { StarIcon } from "@heroicons/react/24/solid"


const Sidebar = () => {
  return (
    <nav
      id="sidebar"
      className="p-2 mt-5 max-w-2xl xl:min-w-fit sticky top-20 flex-grow-0.2 text-center h-screen"
    >
      <div id="navigation">
        <SidevarNavigationItem Icon={<HomeIcon />} name="Homepage" source="/" />
        <SidevarNavigationItem
          Icon={<StarIcon />}
          name="Tournaments"
          source="/tournaments"
        />
       
      </div>
    </nav>
  )
}

export default Sidebar
Run Code Online (Sandbox Code Playgroud)

侧边栏导航项.tsx

import Link from "next/link"
import { FunctionComponent } from "react"

interface Props {
  Icon: React.ElementType
  name: string
  source: string
}

const SidevarNavigationItem: FunctionComponent<Props> = ({
  Icon,
  name,
  source,
}) => {
  return (
    <Link href={source}>
      <div className="flex items-center cursor-pointer text-3xl space-x-5 justify-center">
        {Icon && <Icon classname="h-8 w-8 text-red-500" />}
        <p className="hidden sm:inline-flex font-medium">{name}</p>
      </div>
    </Link>
  )
}

export default SidevarNavigationItem
Run Code Online (Sandbox Code Playgroud)

问题是,当类型为 JSX.Element 时,我无法设置作为 props 传递的图标的样式。将图标的类型更改为 React.ElementType 可以让我添加样式,但会在父级中导致错误,提示

类型“Element”不可分配给类型“ElementType”

我该怎么办?

Ahm*_*ınç 5

您需要传递组件引用本身而不是其渲染的 jsx。

因此,在您的Sidebar.tsx组件中,您需要替换这些行:

Icon={<HomeIcon />}
Icon={<StarIcon />}
Run Code Online (Sandbox Code Playgroud)

分别用这些行:

Icon={HomeIcon}
Icon={StarIcon}
Run Code Online (Sandbox Code Playgroud)

最终的代码应该是这样的:

<div id="navigation">
    <SidevarNavigationItem Icon={HomeIcon} name="Homepage" source="/" />
    <SidevarNavigationItem
      Icon={StarIcon}
      name="Tournaments"
      source="/tournaments"
    />
</div>
Run Code Online (Sandbox Code Playgroud)