When I create a union between two object types (A
and B
), I expect a variable assigned to that union type can only take on the shape of either A
or B
.
Unexpectedly, bad
does not have a type error here, even though intuitively it should because it does not satisfy the constraints of A
nor B
. Typescript Playground Link
type A = {a: string}
type B = {a: string, b: string, c: string}
type Foo = A | B
// this should be a type error, but it isn't?
// to be valid, it should either:
// - not have "c" property
// - add the "b" property
const bad: Foo = {
a: "",
c: ""
}
How can I improve Foo
so that the bad
variable will fail with a type error?
What you want is a discriminated union:
type A = { kind: 'A'; a: string };
type B = { kind: 'B'; a: string; b: string; c: string };
type Foo = A | B;
// type error
const invalid: Foo = {
kind: 'B', // discriminant
a: '',
c: '',
};
The discriminant enforces Foo to be exactly of either type A or B.