Typescript Unions and Discriminating Unions

ยท

3 min read

I really really like typescript .... really.

A subject I would like to write about today is Union types. And how to discriminate Unions with literal type, it's a technique I use a lot in my work when working on possible states of the application (Backend/Frontend).

So what is Union?

As the set theory claims Union is the combination of sets.

Our set is typescript definitions !!!

Take user loading state as example:

interface UserLoadFailed{
    statusCode: number
    message: string
}
interface UserLoading{
   isLoading: boolean
   statusCode: number
}
interface UserLoaded{
   data: User
   statusCode: number
}

So when declaring a function to get the current user state:

function getUserState(): UserLoadFailed | UserLoading | User;

const user = getUserState();

console.log(user.statusCode) // is ok because in all of our "sets" / types we have common field named statusCode

console.log(user.data) 
/* we will get an error as we are referencing 
the Union but `data` exists only in one "set"/Type in the union, 
the only fields we can reach are the ones that intersecting (shared across all union types)*/

Discriminating with literal typed field for the problem ๐Ÿ’ช

Changing our interfaces a bit and creating a Union Type

interface UserLoadFailed {
    status: "Failed";
    statusCode: number;
    message: string;
}

interface UserLoading {
   status: "Loading";
   isLoading: boolean;
}

interface UserLoaded {
    status: "Loaded";
    data: User;
}

type UserStateUnion = UserLoadFailed | UserLoading | UserLoaded;

function getUserState(): UserStateUnion;

const user = getUserState()

And now you are union type-safe ๐Ÿ˜‡ TypeSafe ๐Ÿ˜‡

If you want to discover more about Unions go ahead and open the handbook typescript handbook