0

I have made a component MyComponent with react. I would like to define the props for this component.

Usually i do it like

type Props = {
  foo: string
}

const MyComponent = (props: Props) => ...

Here are the props i would like to always be available

selected: string <-- required
onSelect(): void <-- required
margin?: string <-- optional

And the following are two sets that are non-compatible, ie. only one of them can be used.

Set one:

compact?: boolean <-- optional
minWidth?: number <-- optional
maxWidth?: number <-- optional

Set two:

width?: number <-- optional

What is the best way to define these props so that it makes the most sense to the developer using the component? I.e, what gives the best intellisense experience?

1

1 Answer 1

2

You can create a XOR-like behavior by using never:

type Props = {
    selected: string;
    onSelect(): void;
    margin?: string;
} & (
    | {
          compact?: boolean;
          minWidth?: number;
          maxWidth?: number;
          width?: never;
      }
    | {
          compact?: never;
          minWidth?: never;
          maxWidth?: never;
          width?: number;
      }
);

Then when you give it invalid props:

<MyComponent selected="foo" onSelect={() => {}} margin="0" width={0} compact={true} />

You'll get a fairly helpful error:

Type '{ selected: string; onSelect: () => void; margin: string; width: number; compact: true; }' is not assignable to type 'IntrinsicAttributes & Props'. Type '{ selected: string; onSelect: () => void; margin: string; width: number; compact: true; }' is not assignable to type '{ compact?: undefined; minWidth?: undefined; maxWidth?: undefined; width?: number | undefined; }'. Types of property 'compact' are incompatible. Type 'true' is not assignable to type 'undefined'.(2322)

Playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.