title: Is there any way to define two mutually exclusive properties in Typescript?
body: <p><strong>Problem Description</strong></p>
  <p>I want to define two optional properties in an interface in Typescript. One and only one of these two properties must be present in the instance object of this interface.</p>
  <p><strong>What I have tried</strong></p>
  <pre><code>interface ISidebarCommon {
    /**
     * The label to be used in sidebar
     */
    label: string;
    /**
     * Icon class in string format for the icon of the sidebar image
     */
    icon: string;
  }
  
  interface IRoutableSidebarItem extends ISidebarCommon {
    /**
     * Role number to determine which route to redirect the user to
     * This property is mutually exclusive with children
     */
    role: number;
  }
  
  interface ITreeSidebarItem&lt;SI&gt; extends ISidebarCommon {
    /**
     * An array of children sidebar items.
     * This property is mutually exclusive with role
     */
    children: SI[];
  }
  
  interface ISidebar {
    [index: number]: IRoutableSidebarItem | ITreeSidebarItem&lt;IRoutableSidebarItem
      | ITreeSidebarItem&lt;IRoutableSidebarItem&gt;
    &gt;;
  }
  </code></pre>
  <p><strong>Problem with current solution</strong></p>
  <p>While the current solution makes sure that one of the two properties, i.e, <code>role</code> and <code>children</code>, must be present, it does not make them mutually exclusive. That is, both <code>role</code> and <code>children</code> may be present in the instance object and it will still pass the current interface check.</p>
  <p><strong>Sample of Problem</strong></p>
  <p>The following is an example of an instance of the <code>ISidebar</code> interface where the objects contain both <code>role</code> and <code>children</code> and the linter still doesn't show any errors:</p>
  <pre><code>const sidebarBroken: ISidebar = [
    {
      label: 'l1',
      icon: 'c1',
      role: 5,
      children: [
        {
          label: 'l2',
          icon: 'c2',
          role: 6,
          children: [
            {
              label: 'l3',
              icon: 'c3',
              role: 7,
            },
          ],
        },
      ],
    },
  ];
  </code></pre>