React TS - передача типов в стилизованные компоненты - PullRequest
0 голосов
/ 21 февраля 2020

Итак, у меня есть компонент Navigation, который будет переключать цвет фона для компонента при его нажатии. Моя open prop выдает мне следующую ошибку:

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

Спасибо за любую помощь заранее!

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Вы используете один и тот же интерфейс для компонента 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")};
`;
0 голосов
/ 21 февраля 2020

Ах, в Navigation.tsx, в строке 29 измените

background: ${({ open }) => (open ? "red" : "green")};` 

на

background: ${({ open } : { open: any}) => (open ? "red" : "green")};

Это создаст новый экземпляр, поэтому удалите другой.

И как сказал Джексон в своем ответе, создайте его как новый интерфейс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...