UNPKG

rivo

Version:

🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.

107 lines (85 loc) • 3.61 kB
# Rivo The ultimate library you need for composable type-level programming in TypeScript, powered by HKT. ```typescript import type { $, Ask, Flow, List, Num, Ord, Pipe, Show, Sig, Some, Str, Tuple$$Of1 } from "rivo"; // Rivo provides out-of-the-box type level functions, following point-free style type R1 = Pipe<[-1, 0, 1], List.Every<Num.IsPos>>; // ^?: false type R2 = Pipe<123, Show.Show, Str.ToChars, List.Every<Str.IsDigit>>; // ^?: true // These functions can be called using `$` (`Call`) or `Apply`, // or `Pipe` if it accepts only one argument (as you can see above) type R3 = $<Str.Length, "foo">; // ^?: 3 type IsEveryPositive = List.Every<Num.IsPos>; type R4 = $<IsEveryPositive, [1, 2, 3]>; // ^?: true type R5 = $<Str.Concat, "foo", "bar">; // ^?: "foobar" type R6 = $<Str.Append<"bar">, "foo">; // ^?: "foobar" // Use `Sig` to get the signature of a type level function (for debugging) type IsEveryPositiveSig = Sig<IsEveryPositive>; // Type safety is **guaranteed** when using `$` and `Call` type R7 = $<Str.Append<"foo">, 123>; // ~~~ // Type 'number' does not satisfy the constraint 'string' type R8 = $<Str.Append<"foo">, "bar", "baz">; // ~~~~~ // Type 'string' does not satisfy the constraint 'never' type Append42 = Str.Append<42>; // ~~ // Type 'number' does not satisfy the constraint 'string' // You can easily combine multiple type level functions into one using `Flow` type IsNaturalNumberFn = Flow<Show.Show, Str.ToChars, List.Every<Str.IsDigit>>; type R9 = $<IsNaturalNumberFn, 123>; // ^?: true type R10 = $<IsNaturalNumberFn, 123.5>; // ^?: false // Type safety is **still guaranteed** even when using `Flow` and `Pipe` type F1 = Flow<Show.Show, List.Every<Num.IsPos>>; // ~~~~~~~~~~~~~~~~~~~~~ // Type 'string' is not assignable to type 'List<number>' type R11 = Pipe<"123", Str.ToChars, List.Map<Num.IsPos>>; // ~~~~~~~~~~~~~~~~~~~ // Type 'string' is not assignable to type 'number' // Type level functions can be even generic (see `GenericFn` and `GenericResolver` for more info) type R12 = Sig<Flow<Ask<number>, Tuple$$Of1>>; // ^?: (n: number) => readonly [number] type R13 = Sig<Flow<Ask<string>, Tuple$$Of1>>; // ^?: (n: string) => readonly [string] <- Changes based on the input type // Even type-level type classes! CRAZY! (see inside `rivo/typeclass` for more info) type R14 = $<Ord.Compare, 1, 2>; // ^?: -1 type R15 = $<Ord.Compare, Some<42>, Some<43>>; // ^?: -1 type R16 = $<Ord.Compare, Some<Some<55>>, Some<Some<55>>>; // ^?: 0 ``` Build your own type level functions with ease. ```typescript import type { $, Args, Call2, Fn, PartialApply } from "rivo"; import type { Dec } from "rivo/Num/Int/Dec"; interface RepeatStringFn extends Fn<[number, string], string> { def: ([n, s]: Args<this>) => typeof n extends 0 ? "" : `${typeof s}${Call2<RepeatStringFn, Dec<typeof n>, typeof s>}`; } type R1 = $<RepeatStringFn, 3, "foo">; // ^?: "foofoofoo" // You can partial apply the function to create a new function type RepeatString<N extends number> = PartialApply<RepeatStringFn, [N]>; type R2 = $<RepeatString<3>, "foo">; // ^?: "foofoofoo" ``` ... and much more! Rivo provides great documentation and examples to get you started, just explore them! **Note:** Rivo requires TypeScript 5.0 or above. ## Installation ```bash npm install --save-dev rivo # Or yarn add -D rivo # Or pnpm add -D rivo # Or bun install --dev rivo ```