What might be causing confusion is the difference between tagged unions and untagged unions.
A union type "A | B" means "a value of type A or a value of type B". Example:
function f1(): String | Integer {
if (rand()) {
return "hello"
} else {
return 12
}
}
function f2(x: String | Integer) {
switch (typeof x) {
case String: return "string: " + x
case Integer: return "integer: " + x
}
}
The type "String | String" is exactly equivalent to "String".A tagged union (aka sum type) "A + B" means "either a left value or a right value; if it's the left, it has type A, if it's the right it has type B".
function g1(): String + Integer {
if (rand()) {
return Inl("hello")
} else {
return Inr("bye")
}
}
function g2(x: String + String) {
switch (x) {
case Inl(s): return "left value: " + x
case Inr(s): return "right value: " + x
}
}
The type "String + String" has one bit of additional information than just "String".