Express success/failure with values
Elegant error handling that preserves error information without throwing exceptions
Express success/failure with values.
Either represents a value that can be one of two types: Left (typically for errors) or Right (for success values). It’s perfect for operations that can fail with meaningful error information.
import { Either, Left, Right } from "functype/either";
// Creating Either values
const success = Right(42); // Right(42)
const failure = Left("error"); // Left("error")
// Checking state
success.isRight(); // true
failure.isLeft(); // true
// Extracting values
success.orElse(0); // 42
failure.orElse(0); // 0
success.orThrow(); // 42
failure.orThrow(); // throws Error
| Method | Description |
|---|---|
Right(value) | Create a Right (success) value |
Left(error) | Create a Left (error) value |
Either.right(value) | Same as Right() |
Either.left(error) | Same as Left() |
// Map - transform the Right value
Right(5).map((x) => x * 2); // Right(10)
Left("err").map((x) => x * 2); // Left("err") - unchanged
// MapLeft - transform the Left value
Left("err").mapLeft((e) => e.toUpperCase()); // Left("ERR")
Right(5).mapLeft((e) => e.toUpperCase()); // Right(5) - unchanged
// FlatMap - chain operations
Right(5).flatMap((x) => (x > 0 ? Right(x * 2) : Left("negative")));
// Bimap - transform both sides
either.bimap(
(left) => `Error: ${left}`,
(right) => right * 2,
);
// Using fold
const result = either.fold(
(error) => `Failed: ${error}`,
(value) => `Success: ${value}`,
);
// Using match pattern
const message = validateUser(input).fold(
(errors) => `Validation failed: ${errors.join(", ")}`,
(user) => `Welcome, ${user.name}!`,
);
const validateAge = (age: number): Either<string, number> =>
age >= 0 && age <= 120 ? Right(age) : Left("Invalid age");
const validateName = (name: string): Either<string, string> =>
name.length > 0 ? Right(name) : Left("Name required");
// Chain validations
const validateUser = (data: UserInput) =>
validateName(data.name).flatMap((name) =>
validateAge(data.age).map((age) => ({ name, age })),
);
import { Do, $ } from "functype/do";
const result = Do(function* () {
const name = yield* $(validateName(input.name));
const age = yield* $(validateAge(input.age));
const email = yield* $(validateEmail(input.email));
return { name, age, email };
});
// Short-circuits on first Left
either.toOption(); // None for Left, Some(value) for Right
either.toTry(); // Failure for Left, Success for Right
either.toPromise(); // Rejected for Left, Resolved for Right
See full API documentation at functype API docs