simple-either
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

Simple Either

The Either type is a common functional programming pattern that allows you to represent a value that could be one of two possible types: Left or Right. It's particularly useful for handling error scenarios in a more expressive way.

Usage

Installation

Install the simple-either package using NPM:

npm install simple-either

Example of usage

import { Either, left, right } from 'simple-either';

interface Person {
  name: string;
}

interface PersonError {
  cause: string;
}

const createUser = (person: Person): Either<PersonError, Person> => {
  if (!person.name) {
    return left({ cause: 'Attribute name is required.' } as PersonError);
  }

  return right(person);
};

const personWithoutName = createUser({} as Person);
const personWithName = createUser({ name: 'thaua' } as Person);

console.log(personWithoutName.value);     // The value attribute can be PersonError or Person
console.log(personWithName.value);        // The value attribute can be PersonError or Person

console.log(personWithoutName.isLeft());  // Returns true
console.log(personWithName.isLeft());     // Returns false

console.log(personWithoutName.isRight()); // Returns false
console.log(personWithName.isRight());    // Returns true

For even more explicit code and branching, you can use match and map methods as bellow:

Mapping into unique return format
// Previous code here...

interface HttpResponse {
  statusCode: number;
  response: Person | null;
}

const createUserUseCase: Either<PersonError, Person> = createUser({ name: 'validName?' } as Person);

const httpResponse = createUserUseCase.map<HttpResponse>(
  (error: PersonError) => {
    // Do whatever you want with PersonError and return defined type...
    return { 
      statusCode: 400,
      response: null,
    };
  },
  (person: Person) => {
    // Do whatever you want with Person and return defined type...
    return {
      statusCode: 201,
      response: person,
    };
  }
);

// Do whatever you want with your new HttpResponse based on method results :)
Matching correct branch
// Previous code here...

createUserUseCase.match(
  (error: PersonError) => {
    // Will enter here only on Left response
    console.log(error);
  },
  (user: Person) => {
    // Will enter here only on Right response
    console.log(user);
  }
);

In this example, the createUser function returns an Either type, with Left representing an error case (PersonError interface) and Right representing a successful creation (Person interface). This allows for cleaner error handling and more explicit code.

TypeScript Type Narrowing

When using the isLeft and isRight check methods with the Either type, TypeScript intelligently narrows down the value type within the scope of those conditions..

Consider the following examples:

// Previous code here...

function handleError(error: PersonError) {
  console.error(error);
}

function printPerson(person: Person) {
  console.log(person);
}

// These examples will not work, since the ´.value´ attributes can be either Error or Person while the methods expect specific one:
handleError(personWithName.value);     // TypeScript error
handleError(personWithoutName.value);  // TypeScript error
printPerson(personWithName.value);     // TypeScript error
printPerson(personWithoutName.value);  // TypeScript error

// Inside a specific checked scope (with ´.isLeft´ or ´.isRight´), TypeScript will narrow the value type for usage within the scope:
if (personWithName.isRight())     printPerson(personWithName.value);      // Works!
if (personWithName.isLeft())      handleError(personWithName.value);      // Works! (but will not be pass the condition in this example)
if (personWithoutName.isRight())  printPerson(personWithoutName.value);   // Works! (but will not be pass the condition in this example)
if (personWithoutName.isLeft())   handleError(personWithoutName.value);   // Works!

// Simpler and beautier example:

if (personWithName.isRight()) {
  console.log(`User ${personWithName.value.name} created.`);                  // typescript knows the value is a Person
} else {
  console.log(`User not created due to: ${personWithName.value.cause}.`);     // typescript knows the value is a PersonError
}

License

License: MIT

Stay in touch

For questions or inquiries, please contact Thauã Silveira at thaua@outlook.com.

Package Sidebar

Install

npm i simple-either

Weekly Downloads

1

Version

1.1.0

License

MIT

Unpacked Size

14.5 kB

Total Files

19

Last publish

Collaborators

  • thaua