Home > Net >  In Typescript, how can I tell which React functional component a variable is?
In Typescript, how can I tell which React functional component a variable is?

Time:12-10

I have a CustomIcon component that I use sometimes for my icons, and other times I use MUI's icons. I have a type with a variable defined as:

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

This way, I can call ParentComponent either this way:

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

or

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

I want a way to determine from the value of icon if it's using the MUI icon or my CustomIcon.

I've tried various ways to approach this, using typeof, instanceof, and ReturnType but they're all generally limited due to needing a value for the comparison rather than a type.

Is there a way to solve this using a condition, or does it need to be solved another way?

CodePudding user response:

the type of created react component (in the format of <Icon />) is always be JSX.Element, if you need to some type checks, you should pass the component itself into the props

so the component props will be like belows, note that the name is changes to Icon because if you do <icon /> inside, it will be consider you are try to use a native element call icon:

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

but usually I will let the props of CustomIcon (assume it is called CustomIconProps) compatible with SvgIconProps, and the types will be:

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

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

which will be more clear.

and the usage:

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

if you need to pass args to CustomIcon:

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

CodePudding user response:

I want a way to determine from the value of icon

Where do you want to use that?

If you need it to determine another type, for example to type an style prop, you can do something like this:

      type SvgIcon = React.ReactElement<SvgIconProps>

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