Skip to content

Latest commit

 

History

History
82 lines (59 loc) · 2.72 KB

kind-constraints.md

File metadata and controls

82 lines (59 loc) · 2.72 KB



A higher-kinded-type companion to ts-toolbelt


[Guide]: Kind Constraints

Kinds may be embedded with constraints that are enforced at compile-time. This is useful for ensuring that a Kind is applied with a specific type, or that a Kind is applied with a type that satisfies a certain predicate.

Input Constraints

Input constraints are enforced by the Cast type. Cast is a generic that takes in a type and a constraint type.

import { Cast, Kind } from "hkt-toolbelt";

declare abstract class MyKind extends Kind {
  abstract f: (x: Cast<this[Kind._], string>) => typeof x;
}

Here, we specify that MyKind must be applied with a string type. If we try to apply it with a different type, we get a compile-time error:

// @ts-expect-error
type Result = $<MyKind, 1>; // Type '1' is not assignable to type 'string'

Kind Input Constraints

Kinds can take in kinds. This is useful for defining a kind that takes in a kind that satisfies a certain predicate. However - can we specify that a kind can only take in kinds, which themselves only take in strings?

import { Cast, Kind } from "hkt-toolbelt";

declare abstract class MyKind extends Kind {
  abstract f: (x: Cast<this[Kind._], Kind<(x: string) => unknown>>) => typeof x;
}

As defined above, this is totally possible to encode, such that the following will emit an error (because the And type takes in boolean, not a string).

// @ts-expect-error
type Result = $<MyKind, Boolean.And<true>>; // Type 'And<true>' does not satisfy the constraint 'Kind<(x: string) => unknown>'.

Kind Output Constraints

Finally, we can also specify that a kind can only be applied to a kind that outputs a particular type.

import { Cast, Kind } from "hkt-toolbelt";

declare abstract class MyKind extends Kind {
  abstract f: (x: Cast<this[Kind._], Kind<(x: never) => string>>) => typeof x;
}

The never type in the function parameter type specifies that we don't care what the input type is, as long as the output type is a string.