I wrote something like the following code in TypeScript.
The type ABCD is like a state object and its kind property represents the type of the state. Because some of them (kind is 'a' or 'b') have a common additional property extra, I wrote a common type of them as AB. The others don't have an extra property, so I merged them as CD as below.
type AB = {
kind: 'a' | 'b',
extra: string
};
type CD = {
kind: 'c' | 'd'
};
type ABCD = AB | CD;
function printExtra(x: ABCD) {
if (x.kind === 'c' || x.kind === 'd') return;
console.log(x.extra);
}
The function printExtra prints extra property if kind is neither 'c' nor 'd'.
I was convinced the compilation will pass because that if statement asserts x is not CD and because AB is the only candidate for the type, obviously x is AB. But the TypeScript compiler failed to compile with the following message.
Property 'extra' does not exist on type 'ABCD'. Property 'extra' does not exist on type 'CD'.
Why does the above code failed to compile? I have also tried the following code and confirmed it compiles successfully, but if possible I don't want to use it because it is somewhat redundant in my project.
type A = { kind: 'a', extra: string };
type B = { kind: 'b', extra: string };
type C = { kind: 'c' };
type D = { kind: 'd' };
type ABCD = A | B | C | D;