Member-only story

Tagged Unions and Type Guards in TypeScript

Greg Pabian
3 min readMay 31, 2020

--

This article is a continuation of the series of articles on tagged unions in TypeScript. If you haven’t read it yet, you can access the first article here.

Even thought most of the benefits stemming from using tagged unions are immediately available to developers because the TypeScript compiler understands them on the intrinsic level, sometimes we need to help it out to follow through on our intentions regarding structural transformations.

Filtering arrays

For the purpose of the following example, let’s define some structures that describe different types of users:

type AdminUser = {
type: 'ADMIN';
};
type NonAdminUser = {
type: 'NON_ADMIN';
};
type User = AdminUser | NonAdminUser;

It should be relatively easy to define a function that filters out non-admin users (or filters in admins), right? Let’s try to write it then:

const filterAdmins = (
users: ReadonlyArray<User>
): ReadonlyArray<AdminUser> =>
users.filter(({ type }) => type === 'ADMIN');

Unfortunately, it didn’t work as we expected. The type of the array after using .filter is still the original type instead of the planned narrowed one. It appears that TypeScript doesn’t infer anything from the filter function’s callback. For that to happen, we need to use a type guard.

Type Guards

--

--

Greg Pabian
Greg Pabian

Written by Greg Pabian

A Full-stack Software Engineer that loves building products. Disclaimer: https://gist.github.com/grzpab/3cf57878ffce7d5271298ccc473bcb98

No responses yet