I have the following type declarations:
type Root = { r: string };
type A = { a: string };
type B = { b: string };
type Main = Root & (A | B);
You are right about Main
being equivalent to (Root & A) | (Root & B)
you are wrong about the interpretation of union types (|
). A union type means you can assign either type in the union to main
( so either (Root & A)
or (Root & B)
), but you can only access common properties of the union members. In this case the common member is only r
. Since main
ca be either (Root & A)
or (Root & B)
, a
might not exist on main
, so typescript prevents such an access.
To use the members that only exist on one type in the union you need a type guard. In this case an in
type-guard will work best:
const func : (main: Main) => void = main => {
if ('a' in main) {
main.a
} else {
main.b
}
}
You can read more about type guards here