I wrote this library to provide basics construction for writing code in functional style in Typescript. This library doesn't intend to replace other library like lodash but a separate toolbox which you can use with.
Allow to pipe multiple operation on data
import { pipe, Right, Either } from "functools-ts"
pipe(
Right(42),
a => Either.map(a, x => x + 2),
a => Either.map(a, x => x + 4)
)
import { compose } from "functools-ts"
const f = compose(
(a: List<number>) => a.map(x => x * 2),
a => a.reduce((acc, num) => acc + num, 0)
)
f([1, 2, 3, 4]) // 20
import { Option } from "functools-ts"
Option.map(null, n => n + 1) // null
Option.map(5, n => n + 1) // 6
Option.sequence([1, 2, 3, null, 4]) // null
Option.sequence([1, 2, 3, 4]) // [1, 2, 3, 4]
An useful data structure to represent data that need to be fetch
Here the definition
type RemoteData = Unloaded | Pending | Failed<E> | Loaded<A>
I provide basic pattern matching on it like
import {Loaded, RemoteData} from "functools-ts"
const rd = Loaded(42)
RemoteData.match(rd, {
Loaded: x => `Loaded(${x})`,
Pending: () => "Pending",
Failed: error => `Failed(${error.toString()})`,
Unloaded: () => "Unloaded"
})
Data structure to represent data with validation
type FormField<E, A> = Valid<A> | Invalid<E, A>
import { FormField, Validation } from "functools-ts"
const field: FormField<string, number> = Valid(42)
FormField.match(field, {
Valid: x => console.log(x),
Invalid (x, errors) => console.log(errors)
})
// Let's use Validation
const validateNumber = Validation.combine<string, number>(
x => x > 5 ? Valid(x) : Invalid(x, ["must be greater than 5"]),
x => x % 2 === 0 ? Valid(x) : Invalid(x, ["must be divisible by 2"])
)
validateNumber(5) // Invalid(5, ["must be divisible by 2"])
validateNumber(3) // Invalid(3, ["must be greater than 5", "must be divisible by 2"])
validateNumber(6) // Valid(6)
Allow to view a range of the array
const v = ListView(0, 2, [1, 2, 3, 4, 5])
v.at(0) // 2
v.foldLeft((acc, item) => acc + item, 0)
Write pipe allowing asynchronous function
const f = asyncPipe(
(x: number) => x + 42,
x => new Promise<number>(resolve => resolve(x)),
x => x + 4,
x => x + 4
)
f(4) // Promise<number>
f(4).then(console.log) // 58
with async group (parallel operations)
const f = asyncPipe(
asyncGroup((x: List<number>) => x.join(","), x => x.slice(2)),
asyncGroup(
([a, _]) => a.repeat(2),
([_, b]) => b.reduce((acc, n) => acc + n, 0)
),
([a, b]) => a + b
)
f([1, 2, 3, 4]).then(console.log) // "1,2,3,41,2,3,47"