One of the most common points of failures in web applications is client-server interop. A simple change in an upsteam API - renaming a field, changing its type, altering the way non-values are represented - can have catastrophic effects when the user renders the right UI component at exactly the wrong time.
Traditionally, web teams have tried to mitigate these risks with extensive inter-process integration tests. Termed ‘functional’ or ‘end to end’ tests, these automated checks usually spin up entire web browsers, databases and servers just to perform simple validations, provide feedback that is both slow and imprecise, are prone to false positives and have maintenance burdens of their own.
In my recent projects, however, I’ve found that isomorphic TypeScript types and interfaces, used with modern TypeScript features like type guards and predicates, can go a long way to providing much more lightweight validation that’s nearly as robust.