Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
693 views
in Technique[技术] by (71.8m points)

Is there any way to define two mutually exclusive properties in Typescript?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I found a solution for this by making use of the never type in typescript and optional properties.

What I had to do was update my interface declarations in such a that an instance of IRoutableSidebarItem will never have a children property and an instance of ITreeSidebarItem will never have a role property.

Updated example using the above mentioned workaround:

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;
  children?: never;
}

interface ITreeSidebarItem<SI> extends ISidebarCommon {
  /**
   * An array of children sidebar items.
   * This property is mutually exclusive with role
   */
  children: SI[];
  role?: never;
}

interface ISidebar {
  [index: number]: IRoutableSidebarItem | ITreeSidebarItem<IRoutableSidebarItem
    | ITreeSidebarItem<IRoutableSidebarItem>
  >;
}

/*
  Throws a linting error
*/
const sidebarBroken: ISidebar = [
  {
    label: 'l1',
    icon: 'c1',
    role: 5,
    children: [
      {
        label: 'l2',
        icon: 'c2',
        role: 6,
        children: [
          {
            label: 'l3',
            icon: 'c3',
            role: 7,
          },
        ],
      },
    ],
  },
];

/*
  Doesn't throw a linting error
*/
const sidebarWorking: ISidebar = [
  {
    label: 'l1',
    icon: 'c1',
    children: [
      {
        label: 'l2',
        icon: 'c2',
        children: [
          {
            label: 'l3',
            icon: 'c3',
            role: 7,
          },
        ],
      },
    ],
  },
  {
    label: 'l1',
    icon: 'c1',
    role: 12,
  },
];

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...