L = { tag: "a", payload: string } | { tag: "b", payload: number }
R = { tag: "b", payload: number } | { tag: "c", payload: boolean }
T = L | R
whereas a proper sum type `L + R` would have four.For all purposes and intents, the "b" type in L and R should be treated the same, no? What do you gain by not doing that??
As a concrete example, consider a map with a method get(key: K) -> Option<V>. How do you tell the difference between a missing key and a key which contains `null` as a value?
If you have a function that will normally return a string, but can sometimes fail due to reasons, you may wish to yield an error message in the latter case. So you're going to be returning a string, or a string.
It's not what the content of the data is; it's how you're supposed to interpret it. You have two cases, success and failure, and control will flow differently depending on that, not based strictly on the type of data at hand. We just model those cases in a type.
T = {tag: "L", payload: L} | {tag: "R", payload: R}
The real issue is typescript doesn't have pattern-matching, which make operating on these sum types inelegant