Promise in TypeScript Implementation

In this article I will show you how to implement a promise in TypeScript. My implementation uses the monad interface I showed in the last article. I will implement the most common method of the promise class, the then pattern.

What is a Promise?

The promise method in TypeScript allows you to work with asynchronous code. When creating a promise, you have a success callback and an error callback. For example, when you have a method that reads a CSV, then you can call the success callback when the CSV is read and pass its data to the next step. If an error occurred, then you can call the error callback. The following then steps will be skipped and the first next catch statement will run to deal with the error.

For example, this code reads a CSV using promises

Now you can use this function to read a csv. If there is an error, you can deal with that as well.

The nice thing about this, is that the above code is itself a promise. This means that you can re-use it elsewhere in your code base using the same then pattern.

Advantage of using Promises

The then pattern with Promises is useful in TypeScript. This pattern is common with functional programming. Without this pattern, your code would be hard to maintain, because callbacks will be passed around everywhere; and because of these callbacks the code is harder to test.

Let me show you an example of the so called “callback hell”.

In this code, you can see that this pattern becomes cumbersome quickly. There are 3 places to deal with errors, and the indentation makes the code difficult to read.

With promises, you can use the then method. Let’s see in the next section how to implement and use it to improve the code example above.

Promise Implementation

This is my implementation for the promise monad. This class follows the pattern I showed in the previous article about monads.

Now we can use this promise class implementation to rewrite the callbacks into a pipeline with flatMaps.

The error handling of this method is just a single function. You can choose to deal with all errors, or you can deal with just some of them. The types of the error stack nicely, meaning that the compiler will tell you what errors you still need to deal with. In my case, the linting shows that these errors are to be dealt with.

How to use custom Promise implementation in Typescript. Type hints shows what errors to deal with.

Also, the callback functions in the example above now return instances of the same promise class. This means you can now create utils classes for easier testing.

Conclusion

In this article I showed a basic functional programming implementation of a promise. With this implementation, I showcased how you can use the map and flatMap methods to mimic the then behaviour in the Promise class.