Héctor VallsFreelance Software Engineer

Functional programming in Typescript with fp-ts

Recently, I have started using a library called fp-ts in my Node/Typescript projects. This tool enables you to write functional code with types like Either, Option, Monad and all that confusing stuff.

In this post, I will show you how I wrote an authentication HTTP endpoint using Typescript, Express and, of course, fp-ts.

We are going to write an endpoint that receives a JSON with user credentials and returns a JWT token or 401 UNAUTHORIZED response:

POST /signin
{ "email": "bartolo@mail.com", "password": "1234" }`}

First, let's write some boilerplate Express code:

import express from "express"

const app = express()
app.use(bodyParser.json()) //enables json body deserializer
app.post("/signin", handleSignIn)
app.listen(8080)

Even if you have never used Express library before, I think this code is self-explanatory. Let's see how handleSignIn function looks like.

import { fold } from "fp-ts/lib/Either"

function handleSignIn(req: Request, res: Response) {
  const { email, password } = req.body
  fold(replyUnauthorized(res), replyToken(res))(signIn(email, password))
}

In the first line, we basically extract email and password from request body. Nothing special. The second expression is the interesting one. It can be read as "If signIn returns an error, reply with unauthorized response, otherwise, reply with a token". Here are replyUnauthorized and replyToken functions

function replyUnauthorized(res: Response): (error: Error) => void {
  return error => res.status(401).end()
}

function replyToken(res: Response): (token: string) => void {
  return token => res.json({ token })
}

In order to understand how fold function works, we need to introduce Either type first. Let's deep into signIn function:

import { right, left, Either } from "fp-ts/lib/Either"

function signIn(email: string, password: string): Either<Error, string> {
  const isValid: boolean = authenticate(email, password)
  return isValid
    ? right(generateToken(email))
    : left(new Error("bad credentials"))
}

As you see, this function returns Either<Error, string>; it means an Error or a String (the token). Error return type is the left side result, String is the right result. So, we can return left or right with its respective value, using the two functions fp-ts provides for that. With that in mind signIn function code is quite intuitive: it returns a token when credentials are right, or an error otherwise. Comming back to handleSignIn function, we can now understand better what is going on. This is the fold function signature:

function fold<E, A, B>(onLeft: (e: E) => B, onRight: (a: A) => B): (ma: Either<E, A>) => B { ... }

It receives two functions as parameters:

  • onLeft: In our example, replyUnauthorized, that will be executed when Either left result is returned; Error, in this case.
  • onRight: In our example, replyToken, that will be executed when Either right result is returned; string, in this case.

and returns another function that receives the Either value to be evaluated; in our case, the result of signIn function.

We have seen the usage of Either type fold function, but fp-ts is a very powerful library with many other types and operators. If you are considering to start writing functional code in Typescript, you definitely should check it.