tsfun - functional combinator library for TypeScript
tsfun aims at providing simple functional programming idioms in a way
which fit well with the literal based data structures []
and {}
of JavaScript while
at the same time providing accurate TypeScript-typings.
Install
$ npm i tsfun
Pick your functions
import {on, equal, take, update, flow} from 'tsfun'
Or import as module
import * as tsfun from 'tsfun'
JavaScript has two collection data structures which can be
created using literals. Those are Arrays ([]
) and Objects ({}
). We assume Arrays to be non-sparse.
Objects, at least from the perspective taken in tsfun, do not include class instances
(anything else created with new
, apart from Object,
so Array and Date
would not count as an Object here).
Those data structures provide the ground for a couple of abstractions.
First, Arrays and Objects
can be seen as Associatives, meaning they both have keys (indexes, i.e. numbers, in the Array case) as well as
(homogeneous, i.e. same-typed) values. For Arrays we have Array<T> in TypeScript. To encode a view on Object
as an associative collection, tsfun provides Map<T>, analogously. Order in Maps does not matter, while
in Arrays it does. Arrays seen this way are taken as Lists
or Vectors
(based on their JavaScript properties).
There is however another view on Arrays, which is the Set-view, where order does not matter.
Second, Array and Objects can be seen as Records, meaning there are a couple of properties, which have distinctive meanings and types. Think of a Person with the name and age properties for example. Analogously, there exists a view on Arrays, which is the Tuple-view, where the position in the (small) Array has a meaning. Both variants are supported by the TypeScript type system.
Third, there is Struct, which is a mutually nested structure of Tuples and Records.
tsfun revolves around dealing with these data structures and views on them and provide various functions which operate on these abstractions.
Leafs in any of these structures can be of types number
, string
, boolean
, null
, undefined
, which is denoted
by the type Primitive. Class instances
of anything other than Array or Object (which are assumed to be created via literals) are treated as illegal arguments generally.
Note: We ignore the JavaScript Map
collection and the TypeScript Record
type.
- first
- rest
- last
- reverse
- separate
- distribute
- flatten
- flatMap
- take
- takeWhile
- takeRight
- takeRightWhile
- drop
- dropWhile
- dropRight
- dropRightWhile
- takeNth
- takeUntil
- append
- prepend
- zip
- range
- dense
- sort
Associatives are homogeneous (i.e. all values of the same type) Arrays and homogeneous Maps (JavaScript-Objects).
- keys
- values
- keysValues
- copy
- count
- prune
- size
- indices
- all
- any
- lookup
- map
- reduce
- filter
- remove
- forEach
- assoc
Tools for combining curried versions of tsfun functions into larger units.
Structs are TypeScript-Tuples (which are JavaScript-Arrays),
and JavaScript Objects, typed via TypeScript-Interfaces, as well
as combinations, i.e. mutual nestings, thereof. Leafs can be of types
number
, string
, undefined
, null
, boolean
.
JavaScript-Arrays, viewed as sets. Obviously because of the choice of these should be seen as convenience functions for smaller sets.
JavaScript-Arrays, typed as TypeScript-Tuples.
JavaScript-Arrays, typed as TypeScript-Tuples. Used for processes that can fail.
Predicates generally are functions of type (t: T) => boolean
, which
can be passed to higher order functions like filter
, for example.
Comparators generally are functions of type (l: T1) => (t: T2) => boolean
.
$ npm run build && npm t
or
1$ npm run build:watch
2$ npm t
The way of thinking about datastructures I owe mostly to working with Clojure
. I tried to mimic
some principles but without sacrificing any convenience with regards to the use of the existing collection
literals. The writing of library functions like this and the thinking about typing I encountered first and thus
attribute mostly to Functional Programming in Scala
(the red book).
Ascii Art generated with http://www.patorjk.com/software/taag