A union describes several possible shapes. Narrowing uses a runtime check to establish which shape you have at a particular point in the code. typeof is useful for primitives, while an object guard needs to reject null and inspect the required fields. A user-defined predicate can make that checked relationship available to callers. The predicate must tell the truth about the value it accepts. Discriminated unions make another pattern explicit: one literal field selects the payload fields that are valid together. An exhaustive switch can then use never to expose an unhandled member at compile time. You will validate boundaries and preserve successful empty values rather than treating truthiness as a type check.