簡體   English   中英

Typescript,如何判斷一個變量是哪個React函數組件?

[英]In Typescript, how can I tell which React functional component a variable is?

我有一個CustomIcon組件,有時用於我的圖標,有時我使用 MUI 的圖標。 我有一個變量定義為的類型:

type ParentComponentProps = {
  icon: React.ReactElement<SvgIconProps> | typeof CustomIcon;
};

這樣,我可以這樣調用ParentComponent

<ParentComponent icon={<HomeIcon />}/>

要么

<ParentComponent icon={<CustomIcon {...args}/>}/>

我想要一種方法來確定icon是使用 MUI 圖標還是我的CustomIcon的值。 ParentComponent中,我想將 arguments 添加到傳入的icon中,這樣消費者就不必這樣做(例如,除了消費者可能指定的內容之外,我還想添加className類)。

我嘗試了各種方法來解決這個問題,使用typeofinstanceofReturnType但它們通常都受到限制,因為需要比較值而不是類型。

有沒有辦法使用條件來解決這個問題,還是需要另一種方式來解決?

創建的 React 組件的類型(格式為<Icon /> )總是JSX.Element ,如果你需要一些類型檢查,你應該將組件本身傳遞給 props

所以組件道具將如下所示,請注意名稱更改為Icon因為如果你在里面做<icon /> ,它會認為你正在嘗試使用原生元素調用icon

type ParentComponentProps = {
  Icon: React.ComponentType<SvgIconProps> | typeof CustomIcon;
};

但通常我會讓CustomIcon的道具(假設它被稱為CustomIconProps )與SvgIconProps兼容,並且類型將是:

type CustomIconProps = SvgIconProps & {
// ...
};

type ParentComponentProps = {
  Icon: React.ComponentType<SvgIconProps>;
};

這會更清楚。

和用法:

<ParentComponent Icon={HomeIcon}/>
<ParentComponent Icon={CustomIcon}/>

如果您需要將args傳遞給CustomIcon

<ParentComponent Icon={(props: CustomIconProps) => <CustomIcon {...props} {...args}/>}/>

我想要一種方法來確定圖標的值

你想在哪里使用它?

如果您需要它來確定另一種類型,例如鍵入style道具,您可以這樣做:

      type SvgIcon = React.ReactElement<SvgIconProps>

      type ParentComponentProps<Icon extends  SvgIcon | typeof CustomIcon> = {
               icon: Icon;
               style: Icon extends SvgIcon ? Type1 : Type2
        
       };

即使你這樣做:

<ParentComponent
  icon={<CustomIcon {...args}/>}
/>

...您實際上是將ReactElement傳遞給icon道具。

更一般地說,這類似於children道具或任何插槽內容道具。 我們通常將它們鍵入為ReactNode ,它也接受一個string null或一個ReactNode數組。

確實可以從ReactElement中判斷它是由哪個組件構建的,通常是通過查看其type.name屬性,但您需要首先保護它,如Accessing child.type.name in React Typescript 中所述

function ParentComponent({
    icon
}: {
    icon: React.ReactElement
}) {
    if (React.isValidElement(icon) && typeof icon.type === "function") {
        icon.type.name // Okay
    }
    return <></>
}

游樂場鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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