DEV Community

Théo Holander
Théo Holander

Posted on

What missed me in TypeScript, coming from Java

I published my first NPM package !

First, I'd like to precise that this is the first article I write, and I'm open to any suggestion of changes and/or improvements 😉

Few months ago, I discovered TypeScript and fell in love with it. I always loved Javascript since I started programming, but as most of my programming education was based on Java, the lack of static typing has always been a real pain for me.

So TypeScript came to me as the Holy Graal in my Node.js world ! I was just missing one little thing in TypeScript coming from Java : Optional

What is Optional ?

In the Java world, Optional is an interface, introduced in Java 8, which is an abstraction of the Monad pattern.

In other terms, it is a wrapper around any type you want, use to abstract its nullability. Let's take as an example, a function which search a entry in a list

function searchByName<T extends {name: string}>(array: T[], name: string): T | null;
Enter fullscreen mode Exit fullscreen mode

This function should search an entry in the array which has the property name equal to the parameter of the same name. If the function doesn't find any entry with the correct name, it will return null.

With an Optional type, you would write it this way instead :

function searchByName<T extends {name: string}>(array: T[], name: string): Optional<T>;
Enter fullscreen mode Exit fullscreen mode

Why do we need it ?

In our world of modern programming language, we have abstraction for everything. Each instruction we write is a several layers abstraction of some machine code we can't understand. But if we can abstract anything, why the hell do we still have null keyword in almost every programming language ? (At least every language I know)

In my point of view, the null keyword is the least abstracted thing in programming languages and I hate to use it. That's why I missed the Optional interface a lot when I came to TypeScript. So I search for a library providing this kind of feature, but I found none that fully satisfied me.

I always wanted to create something that can be reusable for other programmers one of these days, so I created the optionable library (Yeah the optional name was already taken 😞)

How to use

For now, the optionable library provide the Optionable interface

interface Optionable<T> {
  readonly isPresent: boolean;
  get: () => T;
  getOrElse: (factory: () => T) => T;
  getOrDefault: (defaultValue: T) => T;
  getOrThrow: <E extends ErrorConstructor | Error>(error: E) => T;
  map: <R>(transformer: (value: T) => R) => R;
}
Enter fullscreen mode Exit fullscreen mode

and 3 factory functions

function of<T>(value: T): Optionable<T>;
function ofNullable<T>(value: T): Optionable<T>;
function empty<T>(): Optionable<T>;
Enter fullscreen mode Exit fullscreen mode

Now let's take an example to show how it can be use.

import { Router, Request, Response } from "express";
import { ofNullable, Optional } from "optionable";

const router = Router();

function findUserById(id: string): Optionable<User> {
    return ofNullable(fetchUserTable({ id }));
}

router.get("/user/:id", (req: Request, res: Response) => {
   const { id } = request.params;
   try {
       const user = findUserById(id).orElseThrow(NotFoundError)
   } catch(error: NotFoundError) {
       res.sendStatus(404);
   }
});
Enter fullscreen mode Exit fullscreen mode

This way, you don't to deal with null values and it is a lot cleaner to write and read than classic null-checks.

This is just an example of how you could use it, but I encourage you to use it as much as possible instead of null or undefined.

Closing thoughts

This is the first time I publish a package on NPM so if you want to contribute or have improvements ideas, message me on dev.to or open an issue on the repository, it will be a pleasure ! 😉

Top comments (0)