Trying to design types for Sanctuary (js library focused on functional programming) has posed a challenge. The goal is to define an Ord
type that represents any value with a natural order. In essence, an Ord
can be:
- A built-in primitive type:
number
,string
,Date
,boolean
- A user-defined type that implements the necessary interface (
compareTo
method) - An array containing other
Ord
instances
To articulate this concept, I opted for a union type (with a workaround to handle recurring types), as shown below:
type Ord = boolean | Date | number | string | Comparable<any> | OrderedArray
interface OrderedArray extends Array<Ord> {}
(The code referenced above can be accessed via this typescript playground).
In creating type definitions for functions like compare
, I used generic types with constraints. Here's an example of how it's done in a curried form:
function compare<T extends Ord>(a: T): (b: T) => number
However, when trying to use such a function with literal arguments (e.g., compare(2)(3)
), TypeScript raises an error stating, '3' is not assignable to '2'
. It appears that TypeScript narrows down the type parameter to a literal value ('2') instead of just narrowing it down to number
after the first argument is provided. Is there a way to prevent this from happening or adopt a different approach that would work effectively?