TypeScript Optional
typescript-optional provides an implementation of the `Optional<T>` type, inspired by Java 8+'s `Optional` class, designed to help developers manage the presence or absence of a value without resorting to null or undefined checks. It aims to reduce `NullPointerExceptions` (or `TypeError` in JavaScript) by providing a fluent API for handling nullable values. The current stable version is 2.0.1, though a 3.0.0-alpha.3 pre-release is available, indicating active development. The package has seen irregular release cycles, with a previous 2.0.0 release being abandoned due to deployment issues before 2.0.1 stabilized it. Key differentiators include its strong typing with TypeScript, direct inspiration from Java's `Optional` API (e.g., `isPresent`, `map`, `orElse`), and methods like `orNull()` and `orUndefined()` for easy conversion back to native JavaScript nullable types. It focuses on the core `Optional` functionality, explicitly noting missing methods like `equals` or `toString` compared to its Java counterpart.
Common errors
-
TypeError: optional.isPresent is not a function
cause In `typescript-optional` v2.0.0 and later, `isPresent` (and `isEmpty`) changed from a property accessor to a method.fixChange `optional.isPresent` to `optional.isPresent()` and `optional.isEmpty` to `optional.isEmpty()`. -
TypeError: Cannot retrieve payload from empty Optional
cause You attempted to call the `get()` method on an `Optional` instance that does not contain a value.fixBefore calling `get()`, verify the presence of a value with `optional.isPresent()`, or use alternative methods like `orElse()`, `orElseGet()`, `orNull()`, or `orUndefined()` to safely handle empty optionals. -
TypeError: value must not be null
cause You passed `null` or `undefined` to `Optional.ofNonNull()`, which explicitly requires a non-null/non-undefined argument.fixIf the value might be `null` or `undefined`, use `Optional.ofNullable(value)` instead. Only use `Optional.ofNonNull()` when you are absolutely sure the value is present.
Warnings
- breaking Version 2.0.0 introduced several breaking changes, including `Optional#isPresent` and `Optional#isEmpty` changing from accessors (properties) to methods. `Optional#map` also had its type signature refined, representing that it exactly returns a value whose payload is non-null type, and `Optional.toJSON` was added.
- gotcha The `get()` method will throw a `TypeError` if the `Optional` instance is empty (does not contain a value). This behavior is consistent with Java's `Optional.get()` but is a common source of runtime errors if not properly guarded.
- gotcha The static factory method `Optional.ofNonNull()` will throw a `TypeError` if the provided argument is `null` or `undefined`. It is specifically designed for situations where you expect a non-null value.
- breaking The `v2.0.0` release was initially abandoned due to deployment issues. While `v2.0.1` fixed these, developers targeting `v2` should ensure they use `v2.0.1` or newer to avoid potential problems.
Install
-
npm install typescript-optional -
yarn add typescript-optional -
pnpm add typescript-optional
Imports
- Optional
const { Optional } = require('typescript-optional');import { Optional } from 'typescript-optional'; - Optional (type import)
import { Optional } from 'typescript-optional';import type { Optional } from 'typescript-optional'; - Optional.ofNullable
new Optional(value);
Optional.ofNullable(value);
Quickstart
import { Optional } from "typescript-optional";
// Example with a potentially null string
const userName: string | null = Math.random() > 0.5 ? "Alice" : null;
const optionalUserName: Optional<string> = Optional.ofNullable(userName);
console.log(`Is name present? ${optionalUserName.isPresent()}`);
// Using ifPresentOrElse to handle both cases
optionalUserName.ifPresentOrElse(
(name) => console.log(`Hello, ${name}!`),
() => console.log("User name is not available.")
);
// Map and filter operations
const nameLength: Optional<number> = optionalUserName
.filter((name) => name.length > 3)
.map((name) => name.length);
nameLength.ifPresent((len) => console.log(`Name length (if > 3): ${len}`));
// Providing a default value
const displayUserName: string = optionalUserName.orElse("Guest");
console.log(`Display name: ${displayUserName}`);
// Converting to nullable JavaScript types
const rawName: string | null = optionalUserName.orNull();
console.log(`Raw name (or null): ${rawName}`);