https://github.com/bromne/typescript-optional
Optional (like Java) implementation in TypeScript
https://github.com/bromne/typescript-optional
java-8 optional typescript
Last synced: 10 months ago
JSON representation
Optional (like Java) implementation in TypeScript
- Host: GitHub
- URL: https://github.com/bromne/typescript-optional
- Owner: bromne
- License: mit
- Created: 2017-09-29T17:44:43.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2023-11-16T14:50:47.000Z (about 2 years ago)
- Last Synced: 2025-03-30T00:08:23.944Z (11 months ago)
- Topics: java-8, optional, typescript
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/typescript-optional
- Size: 273 KB
- Stars: 117
- Watchers: 4
- Forks: 16
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TypeScript Optional
[](https://www.npmjs.com/package/typescript-optional)
[](https://www.npmjs.com/package/typescript-optional)
[](https://codecov.io/gh/bromne/typescript-optional)
Optional (like Java) implementation in TypeScript
## Overview
`Optional` is a type which *may* or *may not* contain a *payload* of type `T`.
It provides a common interface regardless of whether an instance is *present* or is *empty*.
This module is inspired by [Optional class in Java 8+](https://docs.oracle.com/javase/10/docs/api/java/util/Optional.html).
The following methods are currently not supported:
- `equals`
- `toString`
- `hashCode`
- `stream`
### Install
```
npm install --save typescript-optional
```
## Usage
### import
```ts
// import Optional type from this module
import { Optional } from "typescript-optional";
```
### creating `Optional` objects
```ts
const nullableString: string | null = /* some nullable value */;
// all the following variables will be parameterized as Optional.
const optional = Optional.ofNullable(nullableString);
const optionalPresent1 = Optional.ofNullable("foo");
const optionalPresent2 = Optional.ofNonNull("foo"); // accepts non-null value (or else throws TypeError)
const optionalEmpty1: Optional = Optional.empty(); // type hinting required
const optionalEmpty2 = Optional.empty(); // or parameterize explicitly
```
### operations
```ts
const optional: Optional = Optional.ofNullable( /* some optional value: null | string */ );
// force to retrieve the payload. (or else throws TypeError.)
// this method is not used match.
optional.get();
// represent whether this is present or not.
optional.isPresent();
// represent whether this is empty or not. (negation of `isPresent` property)
optional.isEmpty();
// if a payload is present, execute the given `consumer`.
optional.ifPresent(value => console.log(value));
// if a payload is present, execute the first argument (`consumer`),
// otherwise execute the second argument (emptyAction).
optional.ifPresentOrElse(value => console.log(value), () => console.log("empty"));
// filter a payload with additional predicate.
optional.filter(value => value.length > 0);
// map a payload with the given mapper.
optional.map(value => value.length);
// map a payload with the given mapper which returns value wrapped with Optional type.
const powerIfPositive: (x: Number) => Optional
= x => (x > 0) ? Optional.ofNonNull(x * x) : Optional.empty();
const numberOptional: Optional = Optional.ofNullable(/* some optional value: null | number */)
numberOptional.flatMap(value => powerIfPositive(value as number));
// if this is present, return this, otherwise return the given another optional.
const another: Optional = Optional.ofNullable(/* ... */);
optional.or(another);
// if this is present retrieve the payload,
// otherwise return the given value.
optional.orElse("bar");
// if a payload is present, retrieve the payload,
// otherwise return a value supplied by the given function.
optional.orElseGet(() => "bar");
// if a payload is present, retrieve the payload,
// otherwise throw an exception supplied by the given function.
optional.orElseThrow(() => new Error());
// if a payload is present, retrieve the payload,
// otherwise return null.
optional.orNull();
// if a payload is present, retrieve the payload,
// otherwise return undefined.
optional.orUndefined();
// return an appropriate result by emulating pattern matching with the given cases.
optional.matches({
present: value => value.length,
empty: () => 0,
})
// convert this to an Option value.
optional.toOption();
```
### prototype-free types
While `Optional`'s fluent interface for method chaining with `prototype` is usually useful and elegant,
relying on `prototype` can cause some problems in certain situations like that an external function copies such objects *except* `prototype`.
For example, `setState` of React reflects the given value as a state except the value's `prototype` (and then you will see "TypeError: undefined is not a function" in runtime though TypeScript compilation has been succeeded!).
To avoid this issue, you have three options that *convert* an `Optional` into a *prototype-free*, or a simple JavaScript object (associative array, string etc.).
- `Optional.orNull`
- `Optional.orUndefined`
- `Optional.toOption`
#### `Optional.orNull` and `Optional.orUndefined`
Using `Optional.orNull` or `Optional.orUndefined` is the simple way to obtain prototype-free objects.
These methods convert an `Optional` into a value of *type union*.
`Optional.orNull` returns `T | null`.
`Optional.orUndefined` returns `T | undefined`. The `T | undefined` type is compatible with [optional parameters and properties](http://www.typescriptlang.org/docs/handbook/advanced-types.html#optional-parameters-and-properties) of TypeScript.
Use `Optional.ofNullable` to restore an Optional value from a value of these type unions.
```ts
const update: (original: T) => T = /* some external function that returns without the prototype */
const optional: Optional = /* some Optional object */;
let nullable: string | null = optional.orNull();
let orUndefined: string | undefined = optional.orUndefined();
// update using external functions!
nullable = update(nullable);
orUndefined = update(orUndefined);
// retore from (string | null).
const optionalFromNullable: Optional = Optional.ofNullble(nullable);
// restore from (string | undefined).
const optionalFromOrUndefined: Optional = Optional.ofNullble(orUndefined);
```
#### `Option.toOption`
As a more explicit way to obtain prototype-free objects, `Optional.toOption` is provided.
This method convert an `Optional` into an object of `Option` type, which conforms to [*discriminated unions*](http://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions) also known as *algebraic data types*.
Refer the [API document](lib/types.ts) of `Option` to learn about the structure.
```ts
const update: (original: Option) => T = /* some external function that returns without the prototype */
const optional: Optional = /* some Optional value */;
let option: Option = optional.toOption();
// update using external functions!
option = update(option);
// restore from Option.
const optionalFromOption: Optional = Optional.from(option);
```
## License
MIT License - [LICENSE.md](LICENSE.md)