[英]How to extend styled-components props and pass to children?
我絞盡腦汁想了解如何擴展帶樣式的組件,這樣我就可以在正確制作 typescript lint 的同時將幾個道具傳遞給它的孩子。 這就是我所擁有的:
// ButtonBase.tsx
export const ButtonBase = styled.button`
background: var(--primary);
border: none;
`;
// IconButton.tsx
type Props = {
iconName: IconProps['name']
};
export const IconButton = forwardRef<HTMLButtonElement, Props>(({
iconName,
...props
}, ref) => (
<ButtonBase
{...props}
ref={ref}
>
<Icon name={iconName}/>
</ButtonBase>
));
但是這個問題是它不允許像as
, theme
等這樣的樣式化組件道具。我已經嘗試了以下設置來獲得不同程度的結果:
從這里開始,照常轉發道具,沒有成功。
type Props = {
iconName: IconProps['name']
};
type IconButtonType = FC<StyledComponentProps<typeof ButtonBase, any, Props, any>>;
export const IconButton: IconButtonType = ({iconName, ...props}) => (...);
ref
不可用,所以補充說。
type IconButtonType = ForwardRefExoticComponent<PropsWithoutRef<StyledComponentProps<typeof ButtonBase, any, Props, any>> & RefAttributes<HTMLButtonElement>>;
使用StyledComponentProps
但出於某種原因,如果我錯過iconName
,TS 不會觸發。
type Props = StyledComponentProps<'button', any, {
iconName: IconProps['name']
}, any>;
嘗試將iconName
分開,現在 TS 驗證iconName
但不建議有關按鈕的任何內容。
type Props = StyledComponentProps<'button', any, any, any> & {
iconName: IconProps['name']
};
我嘗試使用按鈕屬性,但樣式道具不可用。
type Props = HTMLAttributes<HTMLButtonElement> & {
iconName: IconProps['name']
};
這就是我現在所擁有的,但它會拋出一個錯誤, as
prop, "a" is not assignable to type IntrinsicAttributes
type StyledProps<C extends Element, A extends Element = C> = React.ComponentPropsWithRef<C> & {
as?: A
}; // I copied this from styled-components.d.ts
type ButtonBaseProps = StyledProps<'button'>;
type Props = ButtonBaseProps & {
iconName: IconProps['name']
};
這里的目標是讓IconButton
像一個帶as
、 theme
、 ref
和forwardedAs
的樣式化組件一樣工作,同時讓 TS 在消費者端建議和驗證道具。
我想我缺少做這件事的構圖知識。 我嘗試在 inte.net 上搜索,但我認為我的搜索條件不合時宜,我得到了關於合成的不同結果,但沒有一個真正解釋如何在為嵌套子級添加自定義道具時保留 styled-components 道具。 也許它不是要組成的? 在我之前的項目中,我導出了一個帶有icon
變體的Button
並讓消費者進行組合。 這對我來說是新的,所以任何方向將不勝感激。 TIA!
使用
StyledComponentProps
但出於某種原因,如果我錯過iconName
,TS 不會觸發。
你快到了:第 4 類型參數any
指的是這個:
// The props that are made optional by .attrs
A extends keyof any,
...因此,如果您傳遞any
作為類型參數,那么您基本上是在說所有道具都是可選的,因此如果您不提供iconName
則不會出現錯誤。
在您的情況下,您不使用.attrs
方法,因此沒有可選的道具,因此您可以使用never
type 代替。
然后,正如你已經意識到的,我們仍然需要添加as
多態屬性(實際上,還有forwardedAs
),所以我們現在有:
type Props = StyledComponentProps<'button', any, {
iconName: IconProps['name']
}, never // `never` optional'ed attributes from .attrs
> & {
// Add `as` and `forwardedAs` polymorphic props
as?: string | React.ComponentType<any> | undefined;
forwardedAs?: string | React.ComponentType<any> | undefined;
}
() => (<>
<IconButton as={"button"} iconName="foo" />{/* Okay */}
<IconButton />{/* Error: Property 'iconName' is missing in type '{}' but required in type... */}
{/*~~~~~~~~*/}
<IconButton iconName="foo" type="bar" />{/* Error: Type '"bar"' is not assignable to type '"button" | "submit" | "reset" | undefined'. */}
{/* ~~~~*/}
</>);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.