I'm assuming you don't understand why you shouldn't use discriminated unions for server-side validation?
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.
But wouldn't what you're talking about just be a union type? We might be saying the same thing. The "discriminated" part of discriminated union means that you will be performing the runtime validation to check which of Cat or Dog it is, and only once it receives those validations do you have a derived type. By asserting that the object received is Dog only if it has kind:dog bark:string, you've narrowed your type at compile time to only types that have bark.
> But wouldn't what you're talking about just be a union type?
Not really, unless you define any as union of every possible type. Also TypeScript won't realize you have narrowed the type (because it doesn't use such a definition) with all your checking unless you cheat with type guards (which are really just a prettier cast with optional user-created validation).
Then there's also the fact that thanks to getters your narrowing from any may be incorrect, which is probably why you can only narrow to basic types or with an instanceof operator, neither of which will help you with your JSON input.
tl;dr: Discriminated unions won't help you when you're starting out from any, because any is not an union.
True, discriminated unions don't flow from any, but they can be useful for composing types from any.
I suppose I'm saying that the validation function itself is the precursor to discriminated unions being useful. <any> run through a type predicate function or an assertion type function (https://www.typescriptlang.org/docs/handbook/release-notes/t...) produces a typed object that conforms to your requirements for the type.
I definitely do wish there were some way to create these assertions/validators from the types automatically, but I think that might be impossible.
function isAnimal(thing: any): asserts thing is Animal {
if (thing.kind !== "dog" && thing.kind !== "cat && etc){
throw new AssertionError("Not an animal!");
}
```
// ...etc, except that string literals probably exist in an Array or similar, ie types that can be progressively derived / enhanced from the runtime code.
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.