@sprs/ts-hkt
TypeScript icon, indicating that this package has built-in type declarations

0.0.2 • Public • Published

Introduction

This library implements a form of higher-kindedness in TypeScript.

Disclaimer: Unless you already implement a more complex form of higher-kindedness, you are almost certain to inflate the complexity of your codebase by using this utility. Approach the question of adoption with caution and a healthy dose of skepticism.

Usage

To use this library, import tc (shorter alias for TypeConstructor) from @sprs/ts-hkt and extend it, overriding at least the result property.

tc acts like a type-system-level function, with parameters and a return type. tc itself accepts two type parameters, one to constrain the input types (must be a tuple), and one to constrain the output type. (tc <InputTypeConstraint, OutputTypeConstraint>)

Overriding the result property on an interface extending from tc acts as the "body" of the type function.

Example type constructor, Concat:

import { tc } from '@sprs/ts-hkt';

interface Concat extends tc <[string, string], string> {
  result: `${this[0]}${this[1]}`
}

If you were to make up an analagous runtime function that is more-or-less equivalent to the above, it might look like this:

function Concat (str1: string, str2: string): string {
  return `${str1}${str2}`;
}

Apply type parameters with apply to obtain a new type:

import { apply } from '@sprs/ts-hkt';

// interface Concat ...

type GreetSusan = apply <Concat, ['Hola, ', 'Susan'];
// -> type GreetSusan: 'Hola, Susan';

Type constructors created with tc are automatically curried. Partially apply type parameters to obtain a new type function:

import { partial, apply } from '@sprs/ts-hkt';

// interface Concat ...

type Greet = partial <Concat, ['Hello, ']>;
type GreetJohn = apply <Greet, ['John']>;
// -> type GreetJohn: 'Hello, John';

Use call for isomorphic partial and full type function application:

import { call } from '@sprs/ts-hkt';

// interface Concat ...

type Greet = call <Concat, ['Hello, ']>;
type GreetJohn = call <Greet, ['John']>;
// -> type GreetJohn: 'Hello, John';

Implementation

@sprs/ts-hkt simulates type functions using existing TS language features. The core idea is to express a type which depends on other types through a mechanism other than type parameters.

The specific language features used to simulate higher-kinded types are:

  1. this polymorphism in interfaces - the concrete type of this doesn't resolve fully until a property is accessed
  2. Intersection collapse of unknown & T to T

A minimal implementation of higher-kinded types stripped of the additional constraint and partial application features this library provides might look something like the following:

// All type functions extend from this interface
interface TypeConstructor {
  params: unknown;
  result: unknown;
}

type apply <Fn extends TypeConstructor, Params> =
  (Fn & { params: Params })['result'];

// Specific instance of a type function
interface PairOf extends TypeConstructor {
  result: [this['params'], this['params']];
}

type PairOfNumber = apply <PairOf, number>;
// => [number, number]

Readme

Keywords

Package Sidebar

Install

npm i @sprs/ts-hkt

Weekly Downloads

4

Version

0.0.2

License

MIT

Unpacked Size

6.23 kB

Total Files

4

Last publish

Collaborators

  • brett-mitchell