【问题标题】:Typescript React/Nextjs styled-components - passing function as prop to component throws error on missing typeTypescript React/Nextjs styled-components - 将函数作为道具传递给组件会在缺少类型时引发错误
【发布时间】:2021-10-05 07:20:25
【问题描述】:

我是打字稿的新手,在将函数“toggle”作为道具传递给样式化组件“MobileIcon”时遇到打字稿错误。 我已经在接口 IProps 中设置了“toggle”的函数类型并将其添加到 styled-component 中。

Layout.tsx:

import { FunctionComponent as FC, ReactNode, useState } from "react";
import Toolbar from "src/components/Toolbar";

interface IProps {
  main: ReactNode;
}

const Layout: FC<IProps> = ({ main }) => {
  const [isOpen, setIsOpen] = useState<boolean>(false);

  const toggle = () => {
    setIsOpen(!isOpen);
    console.log("toggle ok");
  };

  return (
    <div>
      <nav>
        <Toolbar isOpen={isOpen} toggle={toggle} />
      </nav>
      <main>{main}</main>
    </div>
  );
};

export default Layout;

Toolbar.tsx:

import { FunctionComponent as FC } from "react";
import styled from "styled-components";
import Link from "next/link";

// Components
import Brand from "./Brand";

interface IProps {
  isOpen: boolean;
  toggle: () => void;
}

const Toolbar: FC<IProps> = ({ isOpen, toggle }) => {
  return (
    <Container>
      <Link href="/">
        <a>
          <Brand />
        </a>
      </Link>
      <MobileIcon isOpen={isOpen} onClick={toggle}>...</MobileIcon>
    </Container>
  );
};

export default Toolbar;

样式化组件:

const MobileIcon = styled.div<IProps>`
...
`

错误:

No overload matches this call.
  Overload 1 of 2, '(props: Omit<Omit<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<...>> & { ...; } & IProps, never> & Partial<...>, "theme"> & { ...; } & { ...; }): ReactElement<...>', gave the following error.
    Property 'toggle' is missing in type '{ children: Element[]; isOpen: boolean; onClick: () => void; }' but required in type 'Omit<Omit<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; } & IProps, never> & Partial<...>, "theme">'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<"div", any, IProps, never, "div", "div">): ReactElement<StyledComponentPropsWithAs<"div", any, IProps, never, "div", "div">, string | JSXElementConstructor<...>>', gave the following error.
    Property 'toggle' is missing in type '{ children: Element[]; isOpen: boolean; onClick: () => void; }' but required in type 'Omit<Omit<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof HTMLAttributes<HTMLDivElement>> & { ...; } & IProps, never> & Partial<...>, "theme">'.

任何帮助都会很棒。

【问题讨论】:

  • 贴出MobileIcon范围内的IProps接口,感觉你叫onClick

标签: reactjs typescript next.js styled-components


【解决方案1】:

在您的 JSX 上,您可以这样使用 MobileIcon:

  <MobileIcon isOpen={isOpen} onClick={toggle}>...</MobileIcon>

所以这里MobileIcon的props是isOpen和onClick。你没有切换道具。

你的 MobileIcon 道具界面是:

interface MobileIconProps = {
   isOpen: boolean;
   onClick: () => void;
}

并且可以用作:

const MobileIcon = styled.div<MobileIconProps>

【讨论】:

  • 你拯救了我的一天。 :) 更改后它可以工作。据我了解:我认为 onClick 是组件 MobileIcon 上的正常方法。这与打字稿不同吗?通常在 React 中,我可以直接将 prop 传递给方法。
  • 唯一改变的是我们需要道具的类型。对于原生 HTML 元素,typescript 具有这些 props 的类型,但是对于自定义组件/第三方组件,您必须自己定义 props/从库的类型定义中导入类型。
【解决方案2】:

您的 IProps 指定了一个 toggle 属性。因此,您的 MobileIcon 组件也需要该道具,但您没有在 Toolbar 组件中指定它。

也许您不希望您的MobileIcon 使用IProps 指定的道具,而只是使用{}(无道具)。毕竟,div 没有isOpen 或toggle。

【讨论】:

  • 感谢 Kelvin 的快速回复。 "isOpen" 属性用于样式化组件 MobileIcon 的样式/动画,切换用于在单击组件 = 汉堡菜单图标时调用函数
猜你喜欢
  • 2021-12-28
  • 2018-09-04
  • 2021-08-04
  • 1970-01-01
  • 2019-10-07
  • 2020-03-12
  • 2022-10-13
  • 2022-06-19
  • 2018-12-01
相关资源
最近更新 更多