Arguably the better solution compared to these "algebraic sum types" (they go by countless different names) are set-theoretic union types, used by a few languages such as TypeScript.
They allow for types like "String or Integer". A function which returns a value of type "A" can automatically also be assigned to a variable of type "A or B", and a function which accepts a parameter of type "A or B" can automatically also be passed a variable of type "A". This is not the case for algebraic sum types, which require somewhat inconvenient wrapping or unwrapping.
Unlike algebraic sum types, set-theoretic union types are also not necessarily mutually exclusive. E.g. a number of type "Integer or Float" could be both. Moreover, set-theoretic types can be generalized to arbitrary Boolean combinations of types, e.g. "A or (B and not C)", possibly involving disjunctions, conjunctions, and negations (since {and, or, not} are functionally complete). That's not possible for algebraic sum/product data types. Though there is no mainstream language yet with a set-theoretic type system that supports negation types.
Sum types in the set theoretic approach can be made with `(A & ¬B) | (¬A & B)`, or equivalently `(A | B) & (¬A | ¬B)`.
There's no mainstream language with negation types, but a few good research languages with them, eg MLstruct.
[MLstruct]:https://github.com/hkust-taco/mlstruct
This choice has nice ergonomics but brutal practical cost so that's why languages close to the metal do not want to do this and particularly don't want to go around defaulting to it whereas a language like Typescript is fine with it.