Input validation with user defined type guards

Mark Slade
2 min readMar 25, 2021

You can read more about user defined type guards at the official documentation, but in summary they are basically awesome. If you find an urge to write someArg as someType outside of a type guard function, ask yourself if a type guard could be cleaner.

Consider the following:

Line 11 tells TypeScript to treat request as something more specific, and line 12 is where we back that up with some runtime logic. This is okay, but we’re mixing concerns (input validation and business logic). Let’s rewrite it with a user defined type guard:

We moved the validation logic into a function called isUserRequest, and its return type is defined as request is IGetUserRequest. We’re fundamentally doing the same thing, but relying a little more on TypeScript to get the types we want. Within the clause on line 16, request is treated as an IGetUserRequest.

Runtime type checking like this is needed any time we are dealing with untrustworthy input. It’s also an area of high risk for human error— you’re telling TypeScript to trust that you’ve validated, so you better do it correctly. For this reason, having the validation in its own function like isUserRequest isolates the concern and helps keep that function focused on what it’s intended to do. It’s also very easy to unit test.

Using type assertions

If you’re not a fan of wrapping your main code inside an if {...}, there’s another neat trick. Consider the following:

We didn’t change much, but note that isUserRequest became mustBeUserRequest. And notice it’s new return type, which indicates that if it returns at all, then request must be an instance of IGetUserRequest. Our validation changed slightly to throw an error instead to indicate a failure.

With this approach our handler remains flat. We call our validation routine on line 17 and proceed onwards with a correctly type request object. Of course, this assumes that we have some error handling further up the chain.

--

--

Mark Slade

Full stack web developer, typescript evangelist, human