Power of conditional types in Typescript

Gaurav Soni
4 min readFeb 28, 2021
Photo by Markus Spiske on Unsplash

One of the most loved type system in the javascript world is the typescript type system. It comes with a lot of features. One of the features that we are discussing today is called conditional types.

Conditional types are a lot like a javascript’s ternary operator. Based on the condition, Typescript will decide which type can be assigned to the variable. Conditional types mostly work with generics.

A few words about generics

Generics are created to work over a variety of types. Consider the example from typescript website,

function identity<T>(arg: T): T {
return arg;
}

Here the T is representing the generic type. Typescript decides the value of T dynamically either by type inferencing or we can tell typescript specifically the type. For example,

Typescript generic example

Back to conditional types

Now let’s discuss the conditional types. As we said earlier, conditional types are more like a ternary operator in javascript, below is the example,

conditional type example

As we can see in the above example, if we pass a string to the type IamString, we will get “I am string”, otherwise it’s giving “I am not string”. On the other way, you can also think of conditional types as adding constraints to the generic types. T is extending the string is a constraint here.

Error handling example

In this article, we will take an example of error handling. Consider we are handling the errors in our application. Let say we have two types of errors in the application. 1) Application Error — Error specific to application 2) Error — normal javascript error.

Let say we abstract the ApplicationError class,

Abstract ApplicationError class

Our custom errors will extend this abstract class and add their implementation. For example,

Server Error example

Let us create a conditional type to identify the error type,

Conditional type example

Now if you try to pass an object which has an error that extends ApplicationError, we will get the type ApplicationError otherwise we will get the Error type,

server error example screenshot
error example screenshot

We can also use this type(ErrorType) as a return type of function. Consider a function that extracts an error from the object and returns that error. The one way to implement that function is to use function overloading,

function overloading getError method
getError example with server errorscreenshot
getError example with error screenshot

In the screenshots, Typescript can identify the type of error for us. But consider in future you are having four types of error in the application. Then you need to overload the getError function two more times which might be annoying.

Now Let’s implement the same thing with the condition types,

getError method implementation with conditional types
getError example with server error screenshot
getError example with error screenshot

You can see that we have the same results but without doing overloading. The only thing is we need to tell the typescript compiler the return type of function explicitly by doing <ErrorType<T>>. You can also use any type and typescript will give the same result.

Now consider you are going to add one error type to the application, you can simply nest the ternary operator to accommodate it.

Conditional types for error with additional error type
Screenshot for conditional types for error with additional error type

Summary

The conditional types might look difficult to understand the first time but it’s worth putting effort into exploring the usage of conditional types and using it.

Further Reading:-

https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/

--

--