A higher-kinded-type companion to ts-toolbelt
If the API does not provide a feature, defining a custom Kind in your application logic is somewhat straight-forward. As an example, let's define a Kind that takes in an object and omits all non-string values.
The approach is usually to define the type first using a generic, and then 'wrap' it in a kind construction.
type OmitNonStrings<O extends Record<string, unknown>> = {
[key in keyof O as O[key] extends string ? key : never]: O[key];
};
type Result = OmitNonStrings<{ foo: number; bar: string }>; // { bar: string }
After OmitNonStrings
is available, we can wrap it in a kind as follows:
import { Kind, Type } from "hkt-toolbelt";
interface OmitNonStringsKind extends Kind.Kind {
f(
x: Type._$cast<this[Kind._], Record<string, unknown>>
): OmitNonStrings<typeof x>;
}
The Type._$cast
parameter enforces that this kind must be applied with a subtype of Record<string, unknown>
. This is a useful pattern for ensuring that the kind is applied correctly.
Now that OmitNonStringsKind
is available, we can use it in kind combinators like List.Map
to map over a tuple of object types.