1

I'd like to have a type that says:

If there's property container present, also expect property a. If there's item property present, also expect property b. container and item cannot exist both at the same time.

The code I'd assume would look as follows, but it doesn't seem to do the above.

type A = { container: true; a: string } | { item: true; b: number };

How do I build such a type?


null | string seems to mean null OR string, but SomeObject | AnotherObject seems to mean all properties present BOTH in SomeObject and AnotherObject.

Sun
  • 299
  • 1
  • 8
  • Does this answer your question? [TypeScript a | b allows combination of both](https://stackoverflow.com/questions/46370222/typescript-a-b-allows-combination-of-both) – Oleg Valter is with Ukraine Mar 26 '21 at 11:42
  • ^ That's only part of the answer - first, you need to define a XOR-like type that either has `container` or `item`, but not both and not none. Then, add a conditional type that, depending on which property is present, intersects the resulting type with either `{ a:string }` or `{ b: number }`. You could also use a discriminated union, but this definition lacks a discriminant property – Oleg Valter is with Ukraine Mar 26 '21 at 11:44

1 Answers1

1

This may seem hacky, but basically creates an XOR. So if you were to add either item or b to the variable myVar, you would get a typescript error.

type ExampleType =
  | { container: true; a: string; item?: never; b?: never }
  | { item: true; b: number; container?: never; a?: never }

// Adding item or b to the below type, will cause a ts error
const myVar: ExampleType = { container: true, a: 'z' }

So say if the container key is provided, it will expect the key value for a to be present, and will error if item or b were passed.

omeanwell
  • 1,847
  • 1
  • 10
  • 16