# Creating typings for curry using TS 3.x

### Compose all the things 🎉

Functional Programming is all about composing functions together and that means we need to make the output of a function to serve as the input of the next one. In order to do so, it’s convinient to make functions have a similar “shape”, thats why in lambda calculus all functions are *1-ary*, meaning they all receive one argument and return one value.

In modern JavaScript you can achieve that by using arrow functions and passing one parameter at a time, but we lose the ability to call our function with all the parameters at once.

Thats when curry-ing comes in handy as it lets you define your function with all the parameters at once and then call them however you like.

Purely functional languages such as Haskell, Elm or Purescript have curry-ing built-in at it’s core, but in JavaScript we need to use a library such as ramda or make our own function.

If you just want to use curried functions in TypeScript and have the type checker to correctly know what’s what, I recommend you install *ramda* and *@types/ramda *with npm. This post is ment to learn how to create typings for a generic curry function and in the process learn some of the advanced features of TypeScript such as conditional types, richer tuple types and function overloads.

If you want to see the full example, here is a link to the repo.

### Function overload

To create the typings for a generic curry function we’ll start by creating a simple concrete curried function and work our way up.

So we are going to try to curry the **add** function, wich takes two numbers and adds them together. In order to do this, we’ll use function overloads which is a mechanism to provide different call signatures for the same function.

The following type declarations says that if we call **add** with two numbers it will return us the addition, but if we only pass one argument, it will return us a new function, that receives the second number and returns the addition.

Notice that we have three lines with the **add** function, the first two are the function overloads, which specifies the different ways the function can be called, and ends with a “**;**”.** **The third **add** is the implementation of all the overloaded functions, and as such, the type must be generic enough to contemplate all the cases.

The last line is not actually needed to create the **add** function but it’s there to help us understand a different way to describe overloaded functions. If you hover over **OverloadedAdd** in the playground you’ll see that we can describe a curried function of two arguments like this:

Where we assume the functions **add**, **mul **and** div** are defined somewhere as plain JavaScript curried functions (for example using ramda’s or lodash curry) and in here we are only defining it’s type.

With a little refactoring we can extract **Curry1** as the base case, an *1-ary *function.

And from here we can define to the *n-th *that we want

This means that if we have a curried function named **bar** that accepts three arguments we can type it using **Curry3. **This will make **bar** to be overloaded with 3 different call signatures (with one, two or three parameters). If we call **bar(1) **we’ll get a **Curry2** function, because there are still two ways we can pass the remaining arguments.

**Unknown number of arguments**

So far we can type curried functions of *n-th* arguments (we only defined *4-th*, but you get the idea), but the **curry** function must work with functions of any lenght, so we must have a way to indicate TypeScript which **CurryN** type to use, we need conditional typings.

Conditional typings is a feature added in version 2.8 of TypeScript, and they allow us to set a type depending on a condition. It works like the ternary operator but with types. In the following example we can notice that the type of **x** will depend on whether **TypeX** matchs or not with **SomeShape**.

So in our case we’ll define a conditional type called **VariadicCurry** which will help us determine which **CurryN** type to use. The name comes from Variadic Functions which are functions that can receive a variable number of arguments. It works by nesting the type condition, so if **T **is a tuple of four numbers it will return a **Curry4** type, if its a tuple of three, **Curry3**, and so on.

If the type **T** doesn’t match with any of the tuples, we return the new unknown type introduced in TypeScript 3, wich is similar to **any**, but safer in the way that you can’t assign it to every variable, you need to cast it, and ideally after checking it’s type dynamically.

Now we have all the tools to define our curry function 🎉.

There is a lot going so lets break it in pieces. The function **curry **accepts only one argument named **fn**, which is the function to be curried. The return of **curry **will be of type **CurryN **depending on wheter **T** is a *1-tuple*, *2-tuple*, etc. We know **T** will be an *n-tuple* because we defined it inside the angle brackets *<T extends number[]>. *And we define that **fn** will be a function of *n-th *arguments (defined by *…args: T*) that returns a number.

The last part is possible thanks to another set of features added in version 3, which allows you to interact with function parameter lists as tuple types.

With all this in place we have defined the types for our curry function… that only works with numbers. ¯\_(ツ)_/¯️

### Generic parameters

Numbers are great, but we made it this far, lets try to make the function work with all types. We’ll start by making the the return type generic on **R**. We’ll refactor our code making **fn** return a type we know nothing about called **R**. This type propagates all the way trough our other definitions, making each **CurryN** generic on the return type.

Making all **CurryN** generic in their arguments its fairly easy as well, we just have to make our types to accept extra parameters.

And to make **VariadicCurry** and **curry** to use the new parameters we need to do one more “trick”.

The **VariadicCurry** type will now match **T** to a *n-tuple* ignoring the argument type (because we use **any **instead of** number**) and only caring about the *arity *of the tuple. When we return a specific **CurryN** we use the indexed types *T[0], T[1], T[2] and T[3] *to specify the correct arguments types.

And that’s it! We now have the typings for a **curry** function that works with an unknown number of arguments and any type you may think. If you want to try the full code you can browse this repo or use this playground.

If you like this post send love ❤️, all feedback is welcomed. You can follow me on twitter as @sherman3ero for more information on TypeScript and functional programming.