tshkt
TypeScript icon, indicating that this package has built-in type declarations

0.2.0-alpha.2 • Public • Published

Encoding higher-kinded types in TypeScript

Motivation

Higher-kinded types are needed when abstracting over type constructors; one might want to define an interface that captures the behavior of objects that support mapping; e.g.

interface Mappable<A> {
  map<B>(f: (a: A) => B): ???
}

The problem is caused by the return type of map: if Array<T> implements Mappable<T>, we would like to express that mapping over an array returns an array. We would end up with

interface Mappable<F, A> {
  // Assuming `this` is F<A>
  map(f: (a: A) => B): F<B>
}

but this syntax is not supported in TypeScript (TypeScript#1213). This library provides means to express F<B> using the existing semantics of TypeScript.

Usage

Let us have a simple container for values:

import {Repr, Generic, Of} from "tshkt"
class Box<A> {
  [Generic.repr]: Generic<BoxRepr, A> // Explained below
  constructor(private value: A) {}
}

To encode the type constructor Box we write

interface BoxRepr extends Repr {
  type: Box<this["argument"]>
}

and associate Box<A> with Generic<BoxRepr, A> by adding a phantom property with name [Generic.repr] to the shape of Box<A>. Now we can convert a Generic<BoxRepr, A> to Box<A> with

type test1 = Of<BoxRepr, string> // Box<string>

and perform type inference in function parameters:

declare function asVoid<F, A>(fa: Of<F, A>): Of<F, void>
asVoid(new Box(2)) // evaluates to Box<void>

License

MIT

Readme

Keywords

none

Package Sidebar

Install

npm i tshkt

Weekly Downloads

1

Version

0.2.0-alpha.2

License

MIT

Unpacked Size

13.6 kB

Total Files

21

Last publish

Collaborators

  • strax