簡體   English   中英

如何擴展 styled-components 道具並傳遞給孩子?

[英]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>
));

但是這個問題是它不允許像astheme等這樣的樣式化組件道具。我已經嘗試了以下設置來獲得不同程度的結果:

從這里開始,照常轉發道具,沒有成功。

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像一個帶asthemerefforwardedAs的樣式化組件一樣工作,同時讓 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM