Strongly disagree. There are two scenario in my mind where union types have distinct advantage
1) they allow for "anonymous types", suppose a function can receive a List or a Dictionary, you could define a type List_or_Dict or (Either List Dict) or Result<List,Dict>, but all of them require you to either have the same sum type at the call site or declare explicitly whether you have a List or a Dict by choosing a type constructor at call site, thus breaking the polymorphism of the union List|Dict (where `|` means union).
Another similar example would be with a variable x of type List|Dict and a function f that again accept a String|List|Dict, with union types the call f(x) is perfectly valid.
2) the second advantage is that now you can treat constructors as their own type and define type with arbitrary combinations of them. For example you could define three constructor Ok: a -> Ok a, Err: a -> Err a, None: None
and then have an option type defined as Ok a | None and a result type defined as Ok a | Err b. in this situation there would be no need to convert success type of an option into success type of a result as they are already the same type.
This makes type inference extremely more complex but ocaml shows that it can be done (this actually negates my initial point)
I think number one can be handled with type classes. Usually if you want to pass in radically different structures there's some common underlying structure.
type classes sort of solve the same problem and in both rust and haskell they can sort of emulate union types (I have no idea about the details, I am not an expert of subtyping).
Still the usability feature of being able to quickly create arbitrary union types is undeniable (Julia uses something similar as a main source of polymorphism and personally I think it is amazing)