首页 > 解决方案 > 如何在打字稿中为反应组件指定类型?

问题描述

我想将一个反应自定义组件作为属性发送到另一个组件

event-logistics.tsx // component name
    
    import { DateIcon } from "../../ui/icons/DateIcon";
    import LogisticsItem from "./logistics-item";

            <LogisticsItem icon={DateIcon}>
              <time>{humanReadableDate}</time>
            </LogisticsItem>

它在图标属性上给了我这个错误:

JSX element type 'Icon' does not have any construct or call signatures.ts(2604)
const Icon: (({ height, width, color, ...props }: SVGProps<SVGSVGElement>) => Element) | undefined

如您所见,我想将作为反应 SVG 组件的 'DateIcon' 发送到图标属性上的“LogisticsItem”组件

logistics-item.tsx // component name

 import style from "./logistics-item.module.css";
 import { DetailedHTMLProps, LiHTMLAttributes, SVGProps } from "react";

export const LogisticsItem: React.FunctionComponent<
  DetailedHTMLProps<LiHTMLAttributes<HTMLLIElement>, HTMLLIElement> & {
    icon?: ({
      height,
      width,
      color,
      ...props
    }: SVGProps<SVGSVGElement>) => Element;
  }
 > = ({ title, children, icon, ...rest }) => {
  const Icon = icon;
  return (
    <li className={style.item}>
      <span className={style.icon}>
        <Icon />
      </span>
      <span className={style.content}>{children}</span>
    </li>
  );
};

export default LogisticsItem;

标签: reactjstypescriptnext.js

解决方案


只需使用FC<SVGProps<SVGSVGElement>>而不是

{
    icon?: ({
      height,
      width,
      color,
      ...props
    }: SVGProps<SVGSVGElement>) => Element

考虑这个例子:

import React, { FC, createElement } from 'react';
import { DetailedHTMLProps, LiHTMLAttributes, SVGProps } from "react";


export const LogisticsItem: React.FunctionComponent<
  DetailedHTMLProps<LiHTMLAttributes<HTMLLIElement>, HTMLLIElement> & {
    icon: FC<SVGProps<SVGSVGElement>>;
  }
> = ({ title, children, icon, ...rest }) => {
  const Icon = icon;

  return (
    <li>
      <span>
        <Icon />
      </span>
      <span >{children}</span>
    </li>
  );
};

const DateIcon = ({ height = "24px", width = "24px", color = "black", ...props }: React.SVGProps<SVGSVGElement>) => 
  (<svg xmlns="w3.org/2000/svg" width={width} height={height} fill="none" viewBox="0 0 24 24" stroke="currentColor" {...props} > <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> </svg>)

const result = <LogisticsItem icon={DateIcon} />

操场

没有错误


推荐阅读