hkt-toolbelt
Advanced tools
Comparing version 0.19.2 to 0.19.3
147
$/$.d.ts
import { Kind, Function } from ".."; | ||
export type $<F extends Kind.Kind, X extends Kind._$inputOf<F>> = Function._$returnType<(F & { | ||
/** | ||
* `$` is the most fundamental type in `hkt-toolbelt`. `$` is a generic type | ||
* which takes in a type-level function and an input type, and returns the | ||
* resultant output type of the type-level function, when applied to the input. | ||
* | ||
* This is a type-level equivalent of an 'apply' function. | ||
* | ||
* `$` operates via partial application. This means that `$` can be used to | ||
* partially apply a type-level function, and then apply the partially applied | ||
* type-level function to a different input type. All applications of `$` must | ||
* be curried. | ||
* | ||
* ## Higher Order Type-Level Functions | ||
* | ||
* The reason that we use `$` instead of normal generic type parameters is that | ||
* we want to be able to partially apply type-level functions. If we used | ||
* normal generic type parameters, we would not be able to perform partial | ||
* application, nor would we be able to take in or reference 'unapplied' types. | ||
* | ||
* As well, in base TypeScript, generics may not take in other generics. In | ||
* other words, the following is not valid TypeScript: | ||
* | ||
* ```ts | ||
* type Apply<F, X> = F<X>; // 'Type 'F' is not generic.' | ||
* ``` | ||
* | ||
* If we wanted to create a 'Map' type, we would not be able to do so with | ||
* normal generic type parameters. Instead, we would need to use a higher-order | ||
* type-level function. That is what `hkt-toolbelt` provides. | ||
* | ||
* ## Parameters | ||
* | ||
* @param F A type-level function. | ||
* @param X The input type to apply the type-level function to. | ||
* | ||
* ## Examples | ||
* | ||
* ### Basic Usage | ||
* | ||
* @example | ||
* | ||
* For example, `Function.Identity` is a type-level function which takes in one | ||
* argument: the input type. `Function.Identity` returns the input type that was | ||
* passed in. | ||
* | ||
* Applying `Function.Identity` to a type will result in the type that was | ||
* passed in: | ||
* | ||
* ```ts | ||
* import { Kind, Function } from "hkt-toolbelt"; | ||
* type Result = $<Function.Identity, "foo">; // "foo" | ||
* ``` | ||
* | ||
* @example | ||
* | ||
* For example, `String.Append` is a type-level function which takes in two | ||
* arguments: first, the string to append, and second, the string to append to. | ||
* | ||
* Only applying `String.Append` to one argument will result in a partially | ||
* applied type-level function. This partially applied type-level function can | ||
* then be applied to a different input type. | ||
* | ||
* ```ts | ||
* import { Kind, String } from "hkt-toolbelt"; | ||
* type AppendBar = $<String.Append, "bar">; | ||
* type Result = $<AppendBar, "foo">; // "foobar" | ||
* ``` | ||
* | ||
* Intermediary type aliases are not necessary, but they can be useful for | ||
* readability. The following example is equivalent to the previous example. | ||
* | ||
* ```ts | ||
* import { Kind, String } from "hkt-toolbelt"; | ||
* type Result = $<$<String.Append, "bar">, "foo">; // "foobar" | ||
* ``` | ||
* | ||
* ### Advanced Usage | ||
* | ||
* @example | ||
* | ||
* For example, `List.Map` is a type-level function which takes in two | ||
* arguments: first, a type-level function, and second, a list. `List.Map` | ||
* returns a list of the same length as the input list, where each element is | ||
* the result of applying the type-level function to the corresponding element | ||
* in the input list. | ||
* | ||
* This example applies `List.Map` to a partially applied `String.Append` type- | ||
* level function, and a list of strings. The result is a list of strings, where | ||
* each string has been appended with the string "bar". | ||
* | ||
* ```ts | ||
* import { Kind, List, String } from "hkt-toolbelt"; | ||
* type Result = $< | ||
* $<List.Map, $<String.Append, "bar">, | ||
* ["foo", "baz"] | ||
* >; // ["foobar", "bazbar"] | ||
* ``` | ||
* | ||
* This example is a nice demonstration of functionality that cannot easily be | ||
* achieved with normal generic type parameters. | ||
* | ||
* @example | ||
* | ||
* For example, `List.Filter` is a type-level function which takes in two | ||
* arguments: first, a type-level function, and second, a list. `List.Filter` | ||
* will only return the elements of the input list where the type-level | ||
* function returns the type `true`. | ||
* | ||
* This example applies `List.Filter` to a partially applied `String.Includes`, | ||
* and a list of strings. The result is a list of strings, where each string | ||
* includes the string "bar". | ||
* | ||
* Here we show where each intermediary step has been given a type alias. This | ||
* is not necessary, but it can be useful for readability and reusability. | ||
* | ||
* ```ts | ||
* import { Kind, List, String } from "hkt-toolbelt"; | ||
* | ||
* // Does the string include "bar"? | ||
* type IncludesBar = $<String.Includes, "bar">; | ||
* | ||
* // Filter the list for strings that include "bar". | ||
* type FilterForBar = $<List.Filter, IncludesBar>; | ||
* | ||
* // Apply the filter to the list. | ||
* type Result = $< | ||
* FilterForBar, | ||
* ["foo", "foobar", "baz", "barqux"] | ||
* >; // ["foobar", "barqux"] | ||
* ``` | ||
* | ||
* In conclusion, `hkt-toolbelt` provides a powerful set of type-level | ||
* functions, which can be used to create complex type-level logic. The `$` | ||
* type is the most fundamental type in `hkt-toolbelt`, and is used to apply | ||
* type-level functions to input types. | ||
*/ | ||
export type $< | ||
/** | ||
* A higher-order type-level function. | ||
*/ | ||
F extends Kind.Kind, | ||
/** | ||
* The input type of the type-level function. `X` must be a subtype of the | ||
* input type of the type-level function. | ||
*/ | ||
X extends Kind._$inputOf<F>> = Function._$returnType<(F & { | ||
readonly [Kind._]: X; | ||
})["f"]>; |
import { Kind, List } from ".."; | ||
/** | ||
* `$$` is a type-level function in `hkt-toolbelt` that allows users to pipe | ||
* multiple type-level functions together and apply them to an input. | ||
* | ||
* ## Purpose | ||
* | ||
* `hkt-toolbelt` provides a variety of higher-order type-level functions that | ||
* enable users to create complex type-level logic. However, it can be | ||
* challenging to apply multiple type-level functions to an input without | ||
* resorting to using intermediary type aliases. | ||
* | ||
* For example, imagine we want to append a string to a list of strings and | ||
* then join the resulting list. We would write this as the following, using | ||
* `Kind.Pipe`. | ||
* | ||
* `Kind.Pipe` is a type-level function that takes a tuple of type-level | ||
* functions and composes them from left to right. | ||
* | ||
* ```ts | ||
* import { Kind, List, String } from "hkt-toolbelt"; | ||
* | ||
* type Result = $< | ||
* $<Kind.Pipe, | ||
* [ | ||
* $<List.Push, "foo">, | ||
* $<String.Join, " "> | ||
* ]>, | ||
* ["bar", "baz"] | ||
* > // "bar baz foo" | ||
* ``` | ||
* | ||
* This is quite verbose. We can use `$$` to make this code more readable: | ||
* | ||
* ```ts | ||
* import { Kind, List, String, $$ } from "hkt-toolbelt"; | ||
* | ||
* type Result = $$< | ||
* [ | ||
* $<List.Push, "foo">, | ||
* $<String.Join, " "> | ||
* ], | ||
* ["bar", "baz"] | ||
* >; // "bar baz foo" | ||
* ``` | ||
* | ||
* Here, `$$` is being used to pipe `List.Push` and `String.Join` together and | ||
* then apply them to a list of strings. | ||
* | ||
* ## Parameters | ||
* | ||
* @param FX A tuple of type-level functions that will be piped together. | ||
* @param X The input type that the type-level functions will be applied to. | ||
* | ||
* ## Examples | ||
* | ||
* ### Basic Usage | ||
* | ||
* @example | ||
* | ||
* Here's a basic example that uses `$$` to apply a type-level function to an | ||
* input type: | ||
* | ||
* ```ts | ||
* import { Kind, List, $$ } from "hkt-toolbelt"; | ||
* | ||
* type Result = $$< | ||
* [$<List.Push, "bar">, List.Unshift<"foo">], | ||
* [1, 2, 3] | ||
* >; // ["foo", 1, 2, 3, "bar"] | ||
* ``` | ||
* | ||
* Here, `List.Push` and `List.Unshift` are being piped together using `$$` to | ||
* append "bar" to a list of numbers and then prepend "foo". | ||
* | ||
* ## Errors | ||
* | ||
* `$$` will enforce that the Nth type-level function's output is a subtype of | ||
* the (N + 1)th input. If this is not the case, `$$` will return the `never` | ||
* type. | ||
* | ||
* If you receive a `never` type, it can be helpful to use the `Kind.InputOf` | ||
* and `Kind.OutputOf` type-level functions to inspect the input and output | ||
* types of the type-level functions that you are piping together. | ||
*/ | ||
export type $$<FX extends Kind.Kind[], X extends FX extends [] ? unknown : Kind._$inputOf<List._$first<FX>>> = Kind._$pipe<FX, X>; |
import { Kind, Type } from ".."; | ||
/** | ||
* `_$and` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'and' logical operation | ||
* on `T` and `U`. If both `T` and `U` are true, then `_$and` returns true, | ||
* otherwise it returns false. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$and` to determine whether two boolean types are | ||
* both true. In this example, `true` and `false` are passed as type arguments | ||
* to the type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$and<true, false>; // false | ||
* ``` | ||
*/ | ||
export type _$and<T extends boolean, U extends boolean> = [T, U] extends [ | ||
@@ -9,2 +34,25 @@ true, | ||
} | ||
/** | ||
* `And` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'and' logical operation | ||
* on `T` and `U`. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `And` to determine whether two boolean types are | ||
* both true. In this example, `true` and `false` are passed as type arguments | ||
* to the type-level function: | ||
* | ||
* We apply `And` to `true` and `false` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.And, true>, false>; // false | ||
* ``` | ||
*/ | ||
export interface And extends Kind.Kind { | ||
@@ -11,0 +59,0 @@ f(x: Type._$cast<this[Kind._], boolean>): And_T<typeof x>; |
import { Kind, Type } from ".."; | ||
/** | ||
* `_$imply` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'imply' logical | ||
* operation on `T` and `U`. If `T` is true and `U` is false, then `_$imply` | ||
* returns false, otherwise it returns true. | ||
* | ||
* This is also known as the 'logical implication' operator. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$imply` to determine whether a statement is true | ||
* given the truth values of two propositions, `T` and `U`. In this example, | ||
* `true` and `false` are passed as type arguments to the type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$imply<true, false>; // false | ||
* ``` | ||
*/ | ||
export type _$imply<T extends boolean, U extends boolean> = [T, U] extends [ | ||
@@ -9,2 +36,27 @@ true, | ||
} | ||
/** | ||
* `Imply` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'imply' logical | ||
* operation on `T` and `U`. | ||
* | ||
* This is also known as the 'logical implication' operator. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Imply` to determine whether a statement is true | ||
* given the truth values of two propositions, `T` and `U`. In this example, | ||
* `true` and `false` are passed as type arguments to the type-level function: | ||
* | ||
* We apply `Imply` to `true` and `false` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Imply, true>, false>; // false | ||
* ``` | ||
*/ | ||
export interface Imply extends Kind.Kind { | ||
@@ -11,0 +63,0 @@ f(x: Type._$cast<this[Kind._], boolean>): Imply_T<typeof x>; |
import { Type, Kind } from ".."; | ||
/** | ||
* `_$nand` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'nand' logical operation | ||
* on `T` and `U`. If both `T` and `U` are true, then `_$nand` returns false, | ||
* otherwise it returns true. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$nand` to determine whether two boolean types are | ||
* not both true. In this example, `true` and `false` are passed as type | ||
* arguments to the type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$nand<true, false>; // true | ||
* ``` | ||
*/ | ||
export type _$nand<T extends boolean, U extends boolean> = [T, U] extends [ | ||
@@ -9,2 +34,25 @@ true, | ||
} | ||
/** | ||
* `Nand` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'nand' logical operation | ||
* on `T` and `U`. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Nand` to determine whether two boolean types are | ||
* not both true. In this example, `true` and `false` are passed as type | ||
* arguments to the type-level function: | ||
* | ||
* We apply `Nand` to `true` and `false` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Nand, true>, false>; // true | ||
* ``` | ||
*/ | ||
export interface Nand extends Kind.Kind { | ||
@@ -11,0 +59,0 @@ f(x: Type._$cast<this[Kind._], boolean>): Nand_T<typeof x>; |
import { Kind, Type } from ".."; | ||
/** | ||
* `_$nimply` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'not-implies' logical | ||
* operation on `T` and `U`. If `T` is true and `U` is false, then `_$nimply` | ||
* returns true, otherwise it returns false. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$nimply` to determine whether two boolean types | ||
* follow the 'not-implies' logical operation. In this example, `true` and | ||
* `false` are passed as type arguments to the type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$nimply<true, false>; // true | ||
* ``` | ||
*/ | ||
export type _$nimply<T extends boolean, U extends boolean> = [T, U] extends [ | ||
@@ -9,2 +34,25 @@ true, | ||
} | ||
/** | ||
* `Nimply` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'not-implies' logical | ||
* operation on `T` and `U`. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Nimply` to determine whether two boolean types | ||
* follow the 'not-implies' logical operation. In this example, `true` and | ||
* `false` are passed as type arguments to the type-level function: | ||
* | ||
* We apply `Nimply` to `true` and `false` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Nimply, true>, false>; // true | ||
* ``` | ||
*/ | ||
export interface Nimply extends Kind.Kind { | ||
@@ -11,0 +59,0 @@ f(x: Type._$cast<this[Kind._], boolean>): Nimply_T<typeof x>; |
import { Type, Kind } from ".."; | ||
/** | ||
* `_$nor` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'nor' logical operation | ||
* on `T` and `U`. If both `T` and `U` are false, then `_$nor` returns true, | ||
* otherwise it returns false. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$nor` to determine whether two boolean types are | ||
* both false. In this example, `true` and `true` are passed as type arguments | ||
* to the type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$nor<true, true>; // false | ||
* ``` | ||
*/ | ||
export type _$nor<T extends boolean, U extends boolean> = [T, U] extends [ | ||
@@ -9,2 +34,25 @@ false, | ||
} | ||
/** | ||
* `Nor` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'nor' logical operation | ||
* on `T` and `U`. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Nor` to determine whether two boolean types are both | ||
* false. In this example, `true` and `true` are passed as type arguments to the | ||
* type-level function: | ||
* | ||
* We apply `Nor` to `true` and `true` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Nor, true>, true>; // false | ||
* ``` | ||
*/ | ||
export interface Nor extends Kind.Kind { | ||
@@ -11,0 +59,0 @@ f(x: Type._$cast<this[Kind._], boolean>): Nor_T<typeof x>; |
import { Type, Kind } from ".."; | ||
/** | ||
* `_$not` is a type-level function that takes in a boolean type `T`, and | ||
* returns the boolean result of applying the 'not' logical operation on `T`. | ||
* If `T` is true, then `_$not` returns false, otherwise it returns true. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$not` to negate a boolean type: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$not<true>; // false | ||
* ``` | ||
*/ | ||
export type _$not<T extends boolean> = T extends true ? false : true; | ||
/** | ||
* `Not` is a type-level function that takes in a boolean type `T`, and | ||
* returns the boolean result of applying the 'not' logical operation on `T`. | ||
* | ||
* @param T A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Not` to negate a boolean type: | ||
* | ||
* We apply `Not` to `true` using the `$` type-level applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<Boolean.Not, true>; // false | ||
* ``` | ||
*/ | ||
export interface Not extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], boolean>): _$not<typeof x>; | ||
} |
import { Type, Kind } from ".."; | ||
/** | ||
* `_$or` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'or' logical operation | ||
* on `T` and `U`. If either `T` or `U` is true, then `_$or` returns true, | ||
* otherwise it returns false. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$or` to determine whether at least one of two boolean | ||
* types is true. In this example, `true` and `false` are passed as type arguments | ||
* to the type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$or<true, false>; // true | ||
* ``` | ||
*/ | ||
export type _$or<T extends boolean, U extends boolean> = [T, U] extends [ | ||
@@ -9,2 +34,25 @@ false, | ||
} | ||
/** | ||
* `Or` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'or' logical operation | ||
* on `T` and `U`. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Or` to determine whether at least one of two boolean | ||
* types is true. In this example, `true` and `false` are passed as type arguments | ||
* to the type-level function: | ||
* | ||
* We apply `Or` to `true` and `false` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Or, true>, false>; // true | ||
* ``` | ||
*/ | ||
export interface Or extends Kind.Kind { | ||
@@ -11,0 +59,0 @@ f(x: Type._$cast<this[Kind._], boolean>): Or_T<typeof x>; |
import { Type, Kind } from ".."; | ||
/** | ||
* `_$xnor` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'xnor' logical operation | ||
* on `T` and `U`. If `T` and `U` are equal, then `_$xnor` returns true, | ||
* otherwise it returns false. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Examples | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$xnor` to determine whether two boolean types are | ||
* equal. In this example, `true` and `true` are passed as type arguments to the | ||
* type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$xnor<true, true>; // true | ||
* ``` | ||
* | ||
* @example | ||
* | ||
* In this example, `true` and `false` are passed as type arguments to the | ||
* type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$xnor<true, false>; // false | ||
* ``` | ||
*/ | ||
export type _$xnor<T extends boolean, U extends boolean> = T extends U ? true : false; | ||
@@ -6,2 +42,43 @@ interface Xnor_T<T extends boolean> extends Kind.Kind { | ||
} | ||
/** | ||
* `Xnor` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'xnor' logical operation | ||
* on `T` and `U`. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Xnor` to determine whether two boolean types are | ||
* equal. In this example, `true` and `true` are passed as type arguments to the | ||
* type-level function: | ||
* | ||
* We apply `Xnor` to `true` and `true` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Xnor, true>, true>; // true | ||
* ``` | ||
* | ||
* @example | ||
* | ||
* In this example, `true` and `false` are passed as type arguments to the | ||
* type-level function: | ||
* | ||
* We apply `Xnor` to `true` and `false` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Xnor, true>, false>; // false | ||
* ``` | ||
* | ||
* The 'xnor' operation is a logical operation which stands for 'exclusive nor'. | ||
* The xnor operation returns true if and only if its operands are equal. It is | ||
* equivalent to the negation of the xor (exclusive or) operation. | ||
*/ | ||
export interface Xnor extends Kind.Kind { | ||
@@ -8,0 +85,0 @@ f(x: Type._$cast<this[Kind._], boolean>): Xnor_T<typeof x>; |
import { Type, Kind } from ".."; | ||
/** | ||
* `_$xor` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'exclusive or' (xor) | ||
* logical operation on `T` and `U`. If `T` and `U` are the same, then | ||
* `_$xor` returns false, otherwise it returns true. | ||
* | ||
* ## Parameters | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* ## Example | ||
* | ||
* @example | ||
* | ||
* For example, we can use `_$xor` to determine whether two boolean types are | ||
* different. In this example, `true` and `false` are passed as type arguments | ||
* to the type-level function: | ||
* | ||
* ```ts | ||
* import { Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = Boolean._$xor<true, false>; // true | ||
* ``` | ||
*/ | ||
export type _$xor<T extends boolean, U extends boolean> = T extends U ? false : true; | ||
@@ -6,2 +31,43 @@ interface Xor_T<T extends boolean> extends Kind.Kind { | ||
} | ||
/** | ||
* `Xor` is a type-level function that takes in two boolean types, `T` and | ||
* `U`, and returns the boolean result of applying the 'exclusive or' (xor) | ||
* logical operation on `T` and `U`. | ||
* | ||
* @param T A boolean type. | ||
* @param U A boolean type. | ||
* | ||
* @example | ||
* | ||
* For example, we can use `Xor` to determine whether two boolean types are | ||
* different. In this example, `true` and `false` are passed as type arguments | ||
* to the type-level function: | ||
* | ||
* We apply `Xor` to `true` and `false` respectively using the `$` type-level | ||
* applicator: | ||
* | ||
* ```ts | ||
* import { $, Boolean } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<$<Boolean.Xor, true>, false>; // true | ||
* ``` | ||
* | ||
* ### Exclusive Or (XOR) Operation | ||
* | ||
* The 'exclusive or' operation (XOR) is a logical operation that outputs true | ||
* only when the inputs differ. In other words, it returns false when the | ||
* inputs are the same. | ||
* | ||
* Here's a truth table for the XOR operation: | ||
* | ||
* | Input A | Input B | Output | | ||
* | ------- | ------- | ------ | | ||
* | true | true | false | | ||
* | true | false | true | | ||
* | false | true | true | | ||
* | false | false | false | | ||
* | ||
* The XOR operation can also be thought of as the negation of the equality | ||
* operation (i.e., `A !== B` is equivalent to `A ^ B`). | ||
*/ | ||
export interface Xor extends Kind.Kind { | ||
@@ -8,0 +74,0 @@ f(x: Type._$cast<this[Kind._], boolean>): Xor_T<typeof x>; |
import { Type, Kind } from ".."; | ||
type _$composablePair<F extends [Kind.Kind, Kind.Kind]> = Kind._$outputOf<F[1]> extends Kind._$inputOf<F[0]> ? true : false; | ||
export type _$composablePair<F extends [Kind.Kind, Kind.Kind]> = Kind._$outputOf<F[1]> extends Kind._$inputOf<F[0]> ? true : false; | ||
export interface ComposablePair extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], [Kind.Kind, Kind.Kind]>): _$composablePair<typeof x>; | ||
} | ||
export {}; |
{ | ||
"name": "hkt-toolbelt", | ||
"version": "0.19.2", | ||
"version": "0.19.3", | ||
"description": "Functional and composable type utilities", | ||
@@ -5,0 +5,0 @@ "types": "./dist/index.d.ts", |
import { Type, Kind, List } from ".."; | ||
export type _$join<T extends string[], D extends string = "", O extends string = ""> = List._$isVariadic<T> extends true ? string : T extends [infer Head, ...infer Tail] ? Tail extends [] ? `${O}${O extends "" ? "" : D}${Type._$cast<Head, string>}` : _$join<Type._$cast<Tail, string[]>, D, `${O}${O extends "" ? "" : D}${Type._$cast<Head, string>}`> : string[] extends T ? `${O}${string}` : O; | ||
export type _$join<T extends (string | unknown)[], D extends string = "", O extends string = ""> = List._$isVariadic<T> extends true ? string : T extends [infer Head, ...infer Tail] ? Tail extends [] ? `${O}${O extends "" ? "" : D}${Type._$cast<Head, string>}` : _$join<Type._$cast<Tail, string[]>, D, `${O}${O extends "" ? "" : D}${Type._$cast<Head, string>}`> : string[] extends T ? `${O}${string}` : O; | ||
interface Join_T<D extends string> extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], string[]>): _$join<typeof x, D>; | ||
f(x: Type._$cast<this[Kind._], (string | unknown)[]>): _$join<typeof x, D>; | ||
} | ||
@@ -6,0 +6,0 @@ export interface Join extends Kind.Kind { |
120412
3270