Home > OS >  Interface value depending on other optional interface value
Interface value depending on other optional interface value

Time:06-13

I have this kind of interface

export interface IButton {
 label: string;
 withIcon?: boolean;
 underlined?: boolean;
 selected?: boolean;
 iconName?: string;
 isLink?: boolean;
 href?: string;
 onCLick?: () => void;
}

Is it possible to make conditionally the use of iconName based on the use of withIcon ?

To make an example:

<Button label='test' /> ---> this should not throw error

<Button withIcon /> this should throw an error that alert me that iconName is missing.

CodePudding user response:

You can achieve this by creating Union type of icon options as follows:

type IconOptions = { withIcon?: false; iconName?: string; } | { withIcon: true; iconName: string; }

What this means is that when withIcon is true, iconName will be required, otherwise it is not required.

You can then append this type as an intersection to IButton which will also need to be a type:

export type IButton = {
 label: string;
 underlined?: boolean;
 selected?: boolean;
 isLink?: boolean;
 href?: string;
 onCLick?: () => void;
} & IconOptions;

Playground link.

CodePudding user response:

This seems to be similar to this quesion.

You can solve it by creating a union of both possible cases.

export type IButton = {
 label: string;
 underlined?: boolean;
 selected?: boolean;
 isLink?: boolean;
 href?: string;
 onCLick?: () => void;
} & ({
 iconName: string;
 withIcon: true
} | {
 iconName?: never;
 withIcon?: never | false
})

This will throw an error if one property is used without the other.

function main(){
  return (
    <>
      <Button label="abc"></Button> // valid
      <Button label="abc" iconName="abc" withIcon></Button> // valid
      <Button label="abc" withIcon></Button> // error: Property 'iconName' is missing in type
      <Button label="abc" iconName="abc"></Button> // error: Property 'iconName' is missing in type
      <Button label="abc" withIcon={false} iconName="abc"></Button> // error: Types of property 'iconName' are incompatible
    </>
  )
}

Playground

  • Related