React TS - 将类型传递给样式化组件

IT技术 reactjs typescript styled-components
2022-07-25 01:44:57

所以我目前有一个导航组件,当它被点击时,它会切换组件的背景颜色。我的openprops给了我以下错误:

var open: any
Binding element 'open' implicitly has an 'any' type.

即使我将我的界面传递给样式化组件:

const StyledBurgerIcon = styled.div<INavigation>`
  align-self: flex-end;
  width: 2em;
  height: 2em;
  background: ${({ open }) => (open ? "red" : "green")};
`;

接口通过:

interface INavigation {
  open: boolean;
  setOpen: (open: boolean) => void;
}

我在 CodeSandBox 上没有收到此错误,但它在 VSCode 中显示此错误:

const BurgerIcon: StyledComponent<"div", any, INavigation, never>
No overload matches this call.
  Overload 1 of 2, '(props: Pick<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | "className" | ... 251 more ... | "onTransitionEndCapture"> & { ...; } & INavigation, "key" | ... 255 more ... | "setOpen"> & Partial<...>, "key" | ... 255 more ... | "setOpen"> & { ...; } & { ...; }): ReactElement<...>', gave the following error.
    Property 'setOpen' is missing in type '{ open: boolean; onClick: () => void; }' but required in type 'Pick<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | "className" | ... 251 more ... | "onTransitionEndCapture"> & { ...; } & INavigation, "key" | ... 255 more ... | "setOpen"> & Partial<...>, "key" | ... 255 more ... | "setOpen">'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<"div", any, INavigation, never>): ReactElement<StyledComponentPropsWithAs<"div", any, INavigation, never>, string | ... 1 more ... | (new (props: any) => Component<...>)>', gave the following error.
    Property 'setOpen' is missing in type '{ open: boolean; onClick: () => void; }' but required in type 'Pick<Pick<Pick<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | "className" | ... 251 more ... | "onTransitionEndCapture"> & { ...; } & INavigation, "key" | ... 255 more ... | "setOpen"> & Partial<...>, "key" | ... 255 more ... | "setOpen">'.ts(2769)
Navigation.tsx(6, 3): 'setOpen' is declared here.
Navigation.tsx(6, 3): 'setOpen' is declared here.

我的导航组件的完整代码:

import * as React from "react";
import styled from "styled-components";

interface INavigation {
  open: boolean;
  setOpen: (open: boolean) => void;
}

const Navigation: React.FC<INavigation> = () => {
  const [open, setOpen] = React.useState(false);

  return (
    <StyledNav>
      <StyledBurgerIcon open={open} onClick={() => setOpen(!open)} />
    </StyledNav>
  );
};

export default Navigation;

const StyledNav = styled.nav`
  display: flex;
  flex-direction: column;
`;
const StyledBurgerIcon = styled.div<INavigation>`
  align-self: flex-end;
  width: 2em;
  height: 2em;
  background: ${({ open }: {open: boolean}) => (open ? "red" : "green")};
`;

这是一个CodeSandBox

提前感谢您的帮助!

1个回答

您对Navigation组件和StyledBurgerIcon.

interface INavigation {
  open: boolean;
  setOpen: (open: boolean) => void;
}

此接口声明了一个必需的属性setOpen,这在您的StyledBurgerIcon

您应该为其创建一个单独的接口,StylesBurgerIcon其中仅包含如下open属性:

interface IBurgerIconProps {
  open: boolean;
}

然后你的样式组件可以使用这个新界面

const StyledBurgerIcon = styled.div<IBurgerIconProps>`
  align-self: flex-end;
  width: 2em;
  height: 2em;
  background: ${({ open }: {open: boolean}) => (open ? "green" : "red")};
`;