0.1.1 • Published 8 years ago

pokato v0.1.1

Weekly downloads
-
License
MIT
Repository
-
Last release
8 years ago

Pokato

A poor man's lens library for TypeScript.

Overview

This is a simple library with functional pseudo-lenses that you may know from languages like Haskell.

Note that there are many great lens-like libraries for JavaScript. If you use JavaScript - use them, not this one! They have much nicer API and are more general. This library was designed specifically to work nice with the TypeScript's type system.

The main issue with making Haskell-like functional lenses work in TypeScript is that its type inference algorithm is not strong enough. And while we can have working lens implementation, we would have to provide generic type annotations virtually everywhere which completely destroys the purpose of lenses - making our lives easier.

Therefore, we end up with this pseudo-lens library. The problem with these pseudo-lenses is that they are not very composable. However, it works just fine for my everyday use case - updating deeply nested values in a Redux store.

Usage

Let us assume you have a JSON like this:

let json = { foo: { bar: { baz: 42 }, quux: "norf" } }

Just import the focus function from this library:

import { focus } from "pokato";

and then use it like this:

focus(json).at("foo").at("bar").at("baz").get()
// => 42

focus(json).at("foo").at("quux").get()
// => "norf"

focus(json).at("foo").at("bar").at("baz").modify((x: number) => x * 2)
// => { foo: { bar: { baz: 84 }, quux: "norf" } }

focus(json).at("foo").at("quux").set("thud")
// => { foo: { bar: { baz: 42 }, quux: "thud" } }

For more usage samples and methods refer to the specification files.

Note that everything is type safe. That is, you can not do something like this:

focus(json).at("bar").get()
// compilation error (missing property "bar")

focus(json).at("foo").at("baz").get()
// compilation error (missing property "baz")

focus(json).at("foo").at("bar").at("baz").set("plugh")
// compilation error (incompatible types `number` and `string`)

You can also update multiple fields of a given object with the then operator:

focus({ foo: 1, bar: { baz: 2, quux: 3 } })
    .then($ => $.at("foo").modify(x => x + 10))
    .then($ => $.at("bar").at("baz").set(5))
    .unfocus()
// => { foo: 11, bar: { baz: 5, quux: 3 } }

Building

Simply use the build script (it should work both with npm and with yarn). There is also a simple Mocha specification that you can check using test script.

yarn build
yarn test
yarn lint