1

I'm a little bit confused with unions of types and arrays.

I have type with the option key, that can takes an array. The array can be made up of a mixture of TOptions or TOptionGroups.

  {
    label: "Generation 1",
    // I shouldn't be able to add 'options' + 'displayName' as they are from different types
    displayName: "This shouldn't be valid",
    options: [
      { displayName: "Bulbasaur", value: "001" },
      { displayName: "Charmander", value: "004" },
      { displayName: "Squirtle", value: "007" },
    ],
    value: "Generation 1",
  },

Should be impossible, but typescript isn't yelling at me - infact it's even offering autocomplete for invalid properties! I've tried adding never and generally playing with the type - but I can't seem to make it strict enough.

type Common = {
  label?: string;
  disabled?: boolean;
};

type TOption = Common & {
  value: string;
  displayName: string;
  selected?: boolean;
};

type TOptionGroup = Common & {
  options: TOption[];
};

export type Props = {
  name: string;
  label: string;
  options: (TOption | TOptionGroup)[];
};


const OPTIONS: Props["options"] = [
  {
    label: "Generation 1",
    // I shouldn't be able to add 'options' + 'displayName' as they are from different types
    displayName: "This shouldn't be valid",
    options: [
      { displayName: "Bulbasaur", value: "001" },
      { displayName: "Charmander", value: "004" },
      { displayName: "Squirtle", value: "007" },
    ],
    value: "Generation 1",
  },
  {
    label: "Generation 2",
    options: [
      { displayName: "Chikorita", value: "152" },
      { displayName: "Cyndaquil", value: "155" },
      { displayName: "Totodile", value: "158" },
    ],
    value: "Generation 2",
  },
];

Typescript Playground

Any pointers would be amazing - think I'm missing something obvious!

Thanks, Ollie

Ollie
  • 1,104
  • 7
  • 24
  • 45
  • ① There are no discriminated unions in this question; just plain old unions. Could you [edit] to fix that? ② See the linked question and answer; if you want to actually prohibit properties from other union members you should make them optional properties of type `never` (or maybe `undefined`). – jcalz May 06 '23 at 22:13

0 Answers0