Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/joanllenas/ts.data.maybe
A Typescript implementation of the Maybe data type
https://github.com/joanllenas/ts.data.maybe
just maybe nothing option typescript
Last synced: 15 days ago
JSON representation
A Typescript implementation of the Maybe data type
- Host: GitHub
- URL: https://github.com/joanllenas/ts.data.maybe
- Owner: joanllenas
- Created: 2018-03-11T00:44:40.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-03-02T10:48:31.000Z (over 3 years ago)
- Last Synced: 2024-10-07T12:10:46.041Z (about 1 month ago)
- Topics: just, maybe, nothing, option, typescript
- Language: TypeScript
- Homepage:
- Size: 39.1 KB
- Stars: 11
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Maybe
[![Build Status](https://travis-ci.org/joanllenas/ts.data.maybe.svg?branch=master)](https://travis-ci.org/joanllenas/ts.data.maybe)
[![npm version](https://badge.fury.io/js/ts.data.maybe.svg)](https://badge.fury.io/js/ts.data.maybe)Maybe encapsulates the idea of a value that might not be there.
A Maybe value can either be `Just` some value or `Nothing`.
```ts
type Maybe = Just | Nothing;
```Where `Nothing` is an instance of `Nothing`, `null` or `undefined`, and `Just` represents any non `Nothing` value.
> If this is new to you, you may want to read the introductory article [Safer code with container types](https://blog.logrocket.com/safer-code-with-container-types-either-and-maybe/) about why and how to use this library.
## Install
```
npm install ts.data.maybe --save
```## Example 1
```ts
import { Maybe, just, withDefault, map2 } from 'ts.data.maybe';interface User {
email: string;
name: Maybe;
surname: Maybe;
}
const user: User = {
email: '[email protected]',
name: just('John'),
surname: just('Doe')
};const getFullName = (name: string, surname: string) => `${name} ${surname}`;
const maybeFullname = map2(getFullName, user.name, user.surname); // Just('John Doe')
console.log(withDefault(maybeFullname, '')); // 'John Doe'
```## Example 2
```ts
const prices: Maybe[] = [
just(300),
nothing(),
just(500),
just(150),
nothing()
];
const sum = (a: number, b: number) => a + b;
const total = prices
.filter(n => !equals(n, nothing()))
.reduce((acc, current) => map2(sum, acc, current), just(0));
console.log(withDefault(total, 0)); // 950
```## Api
_(Inspired by elm-lang)_
### just
`just(value: T): Maybe;`
Wraps a value in an instance of `Just`.
```ts
just(5); // Just(5) (Maybe)
```### nothing
`nothing(): Maybe;`
Creates an instance of `Nothing`.
```ts
nothing(); // Nothing (Maybe)
```> It's recommended to parametrize the function, otherwise the resolved type will be `Maybe` and type won't flow through `map`, `andThen` and so on.
### isJust
`isJust(value: Maybe): value is Just;`
Returns true if a value is an instance of `Just`.
```ts
isJust(nothing()); // false
```### isNothing
`isNothing(value: Maybe): value is Nothing;`
Returns true if a value is an instance of `Nothing`.
```ts
isNothing(just(5)); // false
isNothing(undefined); // true
isNothing(null); // true
isNothing(nothing()); // true
```### withDefault
`withDefault(value: Maybe, defaultValue: A): A;`
If `value` is an instance of `Just` it returns its wrapped value, if it's an instance of `Nothing` it returns the `defaultValue`.
```ts
withDefault(just(5), 0); // 5
withDefault(nothing(), 'hola'); // 'hola'
```### caseOf
`caseOf(caseof: {Just: (v: A) => B; Nothing: () => B;}, value: Maybe): B;`
Run different computations depending on whether a `Maybe` is `Just` or `Nothing` and returns the result.
```ts
caseOf(
{
Nothing: () => 'Do nothing',
Just: n => `Launch ${n} missiles`
},
just(5)
); // 'Launch 5 missiles'
```### map
`map(f: (a: A) => B, value: Maybe): Maybe;`
Transforms a `Maybe` value with a given function.
```ts
const add1 = (n: number) => n + 1;
map(add1, just(4)); // Just(5)
map(add1, nothing()); // Nothing
```There are `map2`, `map3`, `map4`, `map5` and `mapN` functions too:
```ts
map2(
f: (a: A, b: B) => C,
a: Maybe, b: Maybe
): Maybe
```An example with `map2`:
```ts
const safeParseInt = (num: string): Maybe => {
const n = parseInt(num, 10);
return isNaN(n) ? nothing() : just(n);
};
const sum = (x: number, y: number) => x + y;
const safeStringSum = (x: string, y: string) =>
map2(sum, safeParseInt(x), safeParseInt(y));
safeStringSum('1', '2'); // Just(3)
safeStringSum('a', '2'); // Nothing
```If you need to parametrize the function with more than one argument, use the `map` that matches your parametrization.
> `mapN` only accepts arguments of the same type)
```ts
map3(
f: (a: A, b: B, c: C) => D,
a: Maybe, b: Maybe, c: Maybe
): Maybe
``````ts
map4(
f: (a: A, b: B, c: C, d: D) => E,
a: Maybe, b: Maybe, c: Maybe, d: Maybe
): Maybe
``````ts
map5(
f: (a: A, b: B, c: C, d: D, e: E) => F,
a: Maybe, b: Maybe, c: Maybe, d: Maybe, e: Maybe
): Maybe
``````ts
mapN(
f: (...a: A[]) => B,
...a: Maybe[]
): Maybe
```### andThen
`andThen(f: (a: A) => Maybe, v: Maybe): Maybe;`
Chains together many computations that may fail.
```ts
const head = (arr: string[]) => (arr.length > 0 ? just(arr[0]) : nothing());
andThen(head, just(['a', 'b', 'c'])); // Just('a')
andThen(head, just([])); // Nothing
```### equals
`equals(a: Maybe, b: Maybe): boolean;`
Compares two `Maybe` instances and returns `true` when both are `Nothing` or their wrapped values are strictly equal (===), `false` otherwise.
```ts
equals(just(5), just(5); // true
equals(just(6), just(5); // false
equals(nothing(), just(5); // false
equals(nothing(), nothing(); // true
equals(null, nothing(); // true
equals(undefined, nothing(); // true
```