Level up your Typescript game, functionally - Part 3
Tags: typescript, functional, programming, rust
Published: 2023-11-25 01:11:26

Welcome back to the final post in the series "Level up your Typescript game, functionally".

In the previous post, we looked at some functional concepts (like Monads) from the `Scala` programming language and re-implemented those concepts in Typescript with the `Option` and `Either` types.

Now let's look at another useful type from the `Rust` programming language.

### The `Result` type

The extremely type safe `Rust` language exposes a type called `Result` that is very similar to the `Either` type (from Scala/Haskell) but it is exclusively used to model the result of an operation that can either be a Success or Failure (error).

This is what it looks like [ [Source](https://doc.rust-lang.org/std/result/enum.Result.html) ]

```rust
pub enum Result<T, E> {
    Ok(T),
    Err(E),
}
```

Example usage

```rust
let op: Result<i32, &str> = Ok(42);
assert_eq!(x.is_ok(), true);

let x: Result<i32, &str> = Err("Some error message");
assert_eq!(x.is_ok(), false);
``` 

We can implement the `Result` type in Typescript too. Let's modify our `Either` implementation from our previous post and give it a go!

```typescript
type Ok<T> = { value: T }
type Err<E> = { error: E }
// The Result Type
type Result<T, E = Error> = Ok<T> | Err<E>
```

And the util functions to wrap objects

```typescript
export const ok = <T>(value: T): Ok<T> => ({ value })
export const err = <E>(error: E): Err<E> => ({ error })
```

And finally our matchers interface and match function

```typescript
interface Matchers<T, E extends Error, R1, R2> {
    ok(value: T): R1
    err(error: E): R2
}

const match =
    <T, E extends Error, R1, R2>(matchers: Matchers<T, E, R1, R2>) =>
    (result: Result<T, E>) =>
        'value' in result
            ? matchers.ok(result.value)
            : matchers.err(result.error)
```

As you can see this is very similar to the `Either` type implementation but uses `Ok` and `Error` instead of `Left` and `Right`. 

And a practical example from before as follows

```typescript
const getDataFromDB = 
  async (ctx: Context): Promise<Result<Data>> => {
    try {
      const result = await ctx.db.primary.getOne()
      return ok(result)
    } catch (err) {
      console.error('Error getting data from DB', err)
      return err(err)
    }
  }
// using pipe and andThen from the NodeJS 'ramda' package
const app = async () => {
   return pipe(
     getDataFromDB(ctx)
     andThen(
       match({
         err: (err) => throw err,
         ok: (value) => return value
       })
   )
}

```

### Summary

Through this entire series of posts, we saw that we can use pure functional concepts to re-write our Typescript application flows using appropriate types and make our code functionally aware thereby improving dev efficiency and utility especially when it comes to handling domain errors instead of throwing exceptions everywhere. 

### Takeaways and Resources

We learned 4 new functional types to help optimize our code and flows. They are namely `ResultTuple`, `Option`, `Either` and `Result`. 

If you want to use any of these types mentioned in this series, check out this handy [`ts-utils` NodeJS package](https://www.npmjs.com/package/@universal-apps/ts-utils) that I created that encompasses these types as exports so you can use whatever variation makes sense for your use case. To install it simply run this command

```bash
npm i -S @universal-apps/ts-utils
```

The advantage of the types we have discussed in detail in this series is that you can use as much or as little as your want and swap out portions of your codebase without affecting others. 

However if you want to use a full fledged functional library with lots of utilities, I recommend checking out [fp-ts](https://github.com/gcanti/fp-ts) and this handy [cookbook](https://grossbart.github.io/fp-ts-recipes/#/basics) that teaches you how to use it with examples. A newer library called [EffectTS](https://github.com/Effect-TS/effect) that also uses similar concepts and patterns has also been recently gaining popularity if you want to check that out. 

Other libraries to check out are [pratica](https://github.com/rametta/pratica) and [ramda](https://ramdajs.com/)

Last but not least if you want a good learning resource on Functional Programming, check out [this series](https://www.youtube.com/playlist?list=PLuPevXgCPUIMbCxBEnc1dNwboH6e2ImQo) on Youtube. 

### Acknowledgements

I was heavily inspired by [this post](https://imhoff.blog/posts/using-results-in-typescript) from Dan Imhoff on using Results in Typescript for this entire series of posts and extending the concepts.

### Conclusion

Congrats on making it to the end of this final post in the series! You have leveled up once more 🍄🍄🍄 and completed your quest. Thanks for going on this journey with me.

If you found this post and/or series helpful, please upvote/react to it and share your thoughts and feedback in the comments.  

Onwards and upwards 🚀