Earlier quoted context omitted.
This. My network code uses them everywhere on the client side. It's frankly amazing. Your server side code should have runtime validation though. You can't and shouldn't rely on TypeScript there for security reasons.
I don't quite follow. Discriminated unions allow you to derive the type from the runtime validation. If the runtime finds these properties then it must be one of these , but if it finds those then it's one of those. If it can't fit into one of those type buckets as defined by runtime validation, then its . The types flow from the validation algebraically.
Client (JSON) messages will pretty much always start out as any, and you can't assume they fit your union any way shape or form. Taking the Cat|Dog example from the article, a client may pass {"kind":"cat", "bark": "woof"} and if you just go blindly from there to the union and then try to narrow that down, you've got yourself a problem.
You should use a library like JOI (or type guards with custom validation) to first make sure it fits your union type, then you can go wild with discriminated unions.
I always wanted a library that could perform runtime validation given a typescript type, but so far typescript doesn't expose enough type information in decorators for this.