TypeScript Challenge #2: Function currying
Posted on August 5, 2025
Currying is a technique in functional programming where a function with multiple arguments is transformed into a sequence of functions, each with a single argument
For example:
In the above example, curry
transforms the add
function into a curried version that can be called one argument at a time.
Your task is to implement Curry<T>
type so that it recursively transforms a function of multiple arguments into a series of unary functions (each taking one argument).
For example:
Do you know how resolve this challenge? Try to check it with the widget below
💡 Solution
👣 Step 1: Understand Type Inferring
One of the first concepts to grasp is how to extract particular parts of a type structure. This is where the infer
will be used. It's a powerful tool for extracting types that are "trapped" inside any type signature.
The infer
is used within conditional types (ternary expressions)—those written in the form T extends U ? TrueBranch: FalseBranch
. Think of extends
like JavaScript’s ===
, but for types. If the type on the left is assignable to the one on the right, the condition is true and the type resolves to the TrueBranch
otherwise, it falls back to the FalseBranch
.
Let’s start with a simple utility type that checks whether a given type is a function:
Here, we directly compare the structure of the type T
against a signature of the function type. If it matches, we return true
; otherwise, false
.
Now let’s take it a step further and use infer
to extract the particular part of the function type that we are interested in.
A common challenge is to mimic the built-in Parameters<T>
utility type, which constructs a tuple type from the parameters of a function:
Do you know how resolve this challenge? Try to check it with the widget below
Here is the solution of this challenge:
In this example, infer Params
captures the parameter types from the function signature if T
is a function. That inferred type can only be used in the "true" branch of the conditional.

I hope you’ve understood the concept, and to reinforce it, I suggest you try a similar task — this time, we need to implement the built-in utility type ReturnType
, which returns the type of the value returned by a function.
Well, in the previous challenge we inferred ‘argument’ parameters from function signature — for this task is enough just change the place of infer in function signature:
👣 Step 2: Recursive Type Transformation
Now comes the fun part — turning a function type with multiple arguments into a curried version. In essence, we want to take this:
…and turn it into:
I guess if you were solving this task in JavaScript, the first idea that would come to your mind is to use recursion. Luckily for us, TypeScript supports a similar concept.
To really understand how recursion works in TypeScript, it helps to build the right mental model of what a type alias (using the type
keyword) actually is. If you take a look at the syntax and capabilities that TypeScript offers, you’ll notice that type aliases behave in a way that’s quite similar to JavaScript functions.
For example, a type alias without generics is conceptually like a JavaScript function with no arguments:
Now, just as JavaScript functions can accept parameters, TypeScript type aliases can be defined with generic parameters:
We can even go a step further. In JavaScript, we often define default values for parameters to make them optional. TypeScript generics offer a similar mechanism:
One of the most essential shared features between JavaScript functions and TypeScript type aliases is that both can be recursive. Compare:
In TypeScript recursive types, the base case must always be part of one branch of a conditional (ternary) type expression. This ensures the recursion has a stopping point. The other branch should recursively invoke the same type, progressing toward the base case.
Sometimes it makes sense how recursion works with this schema:
By the way, even though you’ve already seen the solution for how to recursively reverse a tuple in TypeScript, try to implement it on your own with widget below — without looking back at the solution. Give yourself a chance to really understand it by doing it hands-on.
I guess you’re now equipped with everything you need to tackle our original task. The first step is to ensure that the provided type is indeed a function. If it is, we can then use infer
to extract its parameter list and return type from the function signature:
As with any recursion, it’s important to begin with the base case. In our scenario, that base case occurs when Args
is an empty tuple — meaning there are no more parameters left to process. When that happens, we simply return the original function’s return type:
Once the base case is in place, we can define the recursive step. If the function has at least one argument, we extract the first one, return a function that takes it, and recursively curry the rest:
Let’s also create a visualization schema of recursion:
🎉 Congratulations! You’ve just solved one of the most challenging and advanced type-level problems in TypeScript.
Ready to take on the challenge again in the widget— this time without peeking at the solution?
Give it a shot and see how much you’ve mastered. Good luck! 💪
When you try the provided solution in the widget, you’ll notice it fails one test case… and that’s intentional 😉. We’ve left it incomplete on purpose — now it’s your turn to get your hands dirty, refine the solution, and make it truly bulletproof.