#reactjs #typescript #styled-components
#reactjs #typescript #styled-компоненты
Вопрос:
У меня есть стилизованный компонент, который выглядит следующим образом:
interface BoxProps {
color?: string;
backgroundColor?: string;
borderColor?: string;
}
export const Box = styled.div<BoxProps>`
position: relative;
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
border: 1px solid transparent;
border-radius: 0.25rem;
text-align: left;
color: ${(props) => props.color};
background-color: ${(props) => props.backgroundColor};
border-color: ${(props) => props.borderColor};
`;
Он заключен в другой компонент:
export const Container: React.FC<ContainerProps> = ({
variant,
children,
...props
}) => {
const { color, backgroundColor, borderColor } = variantColor(variant);
return (
<div>
<Box
color={color}
backgroundColor={backgroundColor}
borderColor={borderColor}
{...props}
>
{children}
</Box>
<p></p>
// ...
</div>
);
};
Если я добавлю StyledComponent<"div", any, BoxProps, never>
к React.FC<ContainerProps>
:
React.FC<ContainerProps amp; StyledComponent<"div", any, BoxProps, never>>
распространение реквизитов выдаст мне следующую ошибку:
Rest types may only be created from object types
Я пытался React.HTMLAttributes<{}> amp; typeof Box.propTypes
и React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
безуспешно…
Есть ли способ объединить стилизованный реквизит компонента с родительским реквизитом?
Спасибо!
Ответ №1:
styled.div
просто визуализируйте a div
, и он принимает любые свойства div
, которые будут принимать ваши свойства от BoxProps
. Вы можете получить тип, который описывает свойства элемента JSX, используя React.HTMLAttributes<HTMLElementYouNeed>
в этом случае React.HTMLAttributes<HTMLDivElement>
, поэтому реквизит Box
теперь будет этим плюсом BoxProps
:
React.FC<ContainerProps amp; React.HTMLAttributes<HTMLDivElement> amp; BoxProps>
Если вам лень это писать, вы можете создать пространство имен утилиты в каком-нибудь файле вашего проекта:
declare namespace HTMLProps {
type div = React.HTMLAttributes<HTMLDivProps>
// Maybe define props for other html elements if you need
}
export default HTMLProps
Затем импортируйте это и используйте
React.FC<ContainerProps amp; HTMLProps.div amp; BoxProps>
Ответ №2:
Ответ Алекса верен, но в некоторых случаях он не будет работать. Например, у меня был этот стилизованный компонент:
export const CustomInput = styled.input.attrs({ type: 'text' })``;
использование:
React.HTMLAttributes<HTMLInputElement>
// or
Omit<React.HTMLAttributes<HTMLInputElement>,'type'>
выдает ошибку в родительском компоненте.
для этого вам нужно:
Omit<React.ComponentPropsWithoutRef<'input'>, 'type'>