Search code examples
reactjstypescripttyping

Typing React Props with variants


I'm working on a React Ts Header that has some variants. the Header Component has two variants Named HomeHeader and DefaultHeader Here only the DefaultHeader needs a required prop title whereas HomeHeader doesn't.

now how to type the HeaderProps HomeHeaderProps and DefaultHeaderProps

the current implementation (not perfect)

interface HeaderProps {
  variant?: "DEFAULT" | "HOME";
  classes?: string;
  title?: string;
};

variant VariantHeaderProps {
   classes?: string;
   title?: string
};

and are used as

const Header: FC<HeaderProps> = ({ variant = "DEFAULT", classes, title })

const DefaultHeader: FC<VariantHeaderProps> = ({ classes, title })

const HomeHeader: FC<VariantHeaderProps> = ({ classes })

Solution

  • Extend a new interface from the HeaderProps and override the title definition to be a required property like so.

    interface DefaultHeaderProps extends HeaderProps {
      title: string;
    };
    

    And declare DefaultHeader with it:

    const DefaultHeader: FC<DefaultHeaderProps> = ({ classes, title })
    

    To make { variant: "DEFAULT", classes, title } also strict do the following by using discriminated unions:

    interface StrictDefaultHeaderProps {
      variant: "DEFAULT";
      classes?: string;
      title: string;
    }
    
    interface StrictHomeHeaderProps {
      variant: "HOME";
      classes?: string;
      title?: string;
    }
    
    type StrictHeaderProps = StrictDefaultHeaderProps | StrictHomeHeaderProps
    
    const Header: FC<StrictHeaderProps> = ({ variant = "DEFAULT", classes, title })