TL;DR: Typescript is unsound so it can add a lot more type-level features that would make a sound type system undecidable
Conceptually no, almost every useful union type can be easily converted to a sum type. In my opinion the difference is in the ergonomics and in the implicit structural subtyping.
For example a common union type is number|string, and the beatiful part is that to use a value of such a type you do not need to do any matching or mapping you can just use the value as it does not have a runtime wrapper, for example (x:string|number)=>JSON.stringify(x) works perfectly fine.
Also you can have a function that takes as input a Array<string>|number|null and returns a string|number without having to declare different contructors for the input number type and the output number type
I believe that you can essentially implement this behaviour by generating enough typeclasses in Haskell, but regardless of the feasibility it, likely, would not be a good idea.
An example of something in between union types an Hindley–Milner sum types are Ocaml's polymorphic variants types https://ocaml.org/manual/5.2/types.html#sss:typexpr-polyvar that are (I believe) more advanced than TS unions but also a lot less ergonomic to use.
And TS has much more eg intersection types you could have a function with type
(x:number)=>string & (x:string)=>number
meaning that it is both a function that maps number to strings and strings to numbers (again you can do this with typeclasses but it is a worse experience)
typescript also has very good support for value types for example there is the string type but also the "hello" type which is the type of only the string "hello"
All in all if someone told me that they implemented typescript in haskell typeclasses I would not call bullshit on them, but I would not believe that anyone would actually use it for anything
Conceptually no, almost every useful union type can be easily converted to a sum type. In my opinion the difference is in the ergonomics and in the implicit structural subtyping.
For example a common union type is number|string, and the beatiful part is that to use a value of such a type you do not need to do any matching or mapping you can just use the value as it does not have a runtime wrapper, for example (x:string|number)=>JSON.stringify(x) works perfectly fine.
Also you can have a function that takes as input a Array<string>|number|null and returns a string|number without having to declare different contructors for the input number type and the output number type
I believe that you can essentially implement this behaviour by generating enough typeclasses in Haskell, but regardless of the feasibility it, likely, would not be a good idea.
An example of something in between union types an Hindley–Milner sum types are Ocaml's polymorphic variants types https://ocaml.org/manual/5.2/types.html#sss:typexpr-polyvar that are (I believe) more advanced than TS unions but also a lot less ergonomic to use.
And TS has much more eg intersection types you could have a function with type
meaning that it is both a function that maps number to strings and strings to numbers (again you can do this with typeclasses but it is a worse experience)typescript also has very good support for value types for example there is the string type but also the "hello" type which is the type of only the string "hello"
All in all if someone told me that they implemented typescript in haskell typeclasses I would not call bullshit on them, but I would not believe that anyone would actually use it for anything