2

I want an object of my type to be either of type AB or of type AB & CD. This code looks correct, but gives me no error when I create the object with only 3 keys.

interface AB {
  a: number;
  b: number;
}

interface CD {
  c: number;
  d: number;
}

type ABorABCD = AB | (AB & CD);

// OK
const ab = {
  a: 1,
  b: 2,
}

// OK
const abcd = {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
}
  
// Should not be OK, but it is
const abc: ABorABCD = {
  a: 1,
  b: 2,
  c: 3,
}

// Should not be OK, but it is
const abc: ABorABCD = {
  a: 1,
  b: 2,
  d: 4,
}
apollov
  • 117
  • 9
  • It's a bit unclear what you want though - given that all the keys are required in both types, your type will naturally only support 2 or 4 keys – Daniel Apr 13 '23 at 17:41
  • @Daniel this is exactly what I want: 2 or 4 keys allowed in my object. Though Ts allows me to create one with 3 keys, which should be prohibited. Updated the question, thank you. – apollov Apr 13 '23 at 17:43
  • Make the other keys `never` and then intersect it with `AB`: https://tsplay.dev/wgvGBW – kelsny Apr 13 '23 at 18:27
  • @pink that SO thread not only answers my question, but also makes me understand now that the union is not mutually exclusive by nature and it allows to have such "mixes" by design, because this is how the union of sets works. Thank you for the clarification and the links, it helped me to understand the lack of my knowledge a bit deeper :) – apollov Apr 13 '23 at 18:47

0 Answers0