Typescript Interface to contain a non-mandatory property or another

Solution 1:

Because TypeScript is structurally-typed, it is not an error for an object to have excess properties, unless you explicitly disallow this by setting the property's optional type to never, like this:

TS Playground

type BlackOptional = {
  black?: boolean;
  white?: never;
};

type WhiteOptional = {
  black?: never;
  white?: boolean;
};

type Name = {
  name: string;
}

type Example = (Name & BlackOptional) | (Name & WhiteOptional);

const example1: Example = { /*
      ^^^^^^^^
Types of property 'black' are incompatible. Type 'boolean' is not assignable to type 'never'.(2322) */
  name: 'name',
  black: true,
  white: true,
};

const example2: Example = {
  name: 'name',
  black: true,
};

const example3: Example = {
  name: 'name',
  white: true,
};