Muhammad Zeeshan
Muhammad Zeeshan

Reputation: 4748

Deciding Runtime Props Typescript

I am creating a component in react.js using typescript. I am stuck for a while to figure out how i can make one prop compulsory either of two. I am creating a Label component. It should either receive an icon or title in props. The way i used to pass props is:

import React, { forwardRef } from 'react';
import clsx from 'clsx';

export interface LabelProps{
  className?: string;
  onClick?: () => void;
  icon: string,
  title: string
}

export const Label = forwardRef<HTMLDivElement, LabelProps>(function(
  { className, onClick, icon, title },
  ref,
) {
  return (
    <div className={clsx(className, 'label')} onClick={onClick} ref={ref}>
      // My Way to display thing's
    </div>
  );
});

export default Label;

Now, i know i can check the value of both icon and title in props and render respectively. But i want typescript to not allow me passing both of them and display an error. I want to use this component as:

<Label icon={icon} />

or

<Label title={title} />

But not as the following. Typescript should complain about this:

<Label icon={icon} title={title} />

Can you show me a way to achieve this?

Upvotes: 2

Views: 433

Answers (1)

Zunaib Imtiaz
Zunaib Imtiaz

Reputation: 3119

You can try doing this. This helps making Props (title, icon) Interdependent, Or No Prop (title, icon) at all.

export interface BaseLabelProps extends HTMLAttributes<HTMLLabelElement> {
  className?: string;
}

interface LabelWithIconProps extends BaseLabelProps {
  icon?: string;
  title?: never;
}

interface LabelWithoutIconProps extends BaseLabelProps {
  icon?: never;
  title?: string;
}

export type LabelProps = LabelWithoutIconProps | LabelWithIconProps;

Upvotes: 5

Related Questions