TypeScript Infers the Last Overload

TypeScript has a specific behavior when you use overloaded functions.

When you try to infer a type from an overloaded function, TypeScript only gives you the last signature.

I ran into this while working with i18next. I wanted to turn string keys into something better. I wanted autocomplete and better developer experience. To do this, I needed to transform existing function types.

The problem: I needed to extract every single call signature from an overloaded type.

Standard TypeScript does not give you a way to do this. Most solutions use hardcoded tables, like supporting only 5 or 10 overloads. I wanted a way to handle any number of signatures.

I found a solution by experimenting with intersections.

Here is the logic:

  • TypeScript infers from the last signature.
  • Intersections (&) can change the order of signatures.
  • If you change the order, you change what TypeScript sees when it infers.

I discovered that intersecting an overloaded type with one of its own signatures moves that signature to the front of the list.

This allowed me to create a recursive type.

The process works like this:

  1. Infer the last visible signature.
  2. Use an intersection to change the alignment.
  3. This forces the next signature to become the new last signature.
  4. Repeat until you have captured every signature in a union.

Once you turn overloads into a union, you can treat them like data. You can transform them, wrap return types in Promises, or rename arguments. After the transformation, you can turn the union back into an intersection to restore the overloaded function.

The full pipeline looks like this: Overloads -> Union -> Transform -> Intersection -> Overloads.

This is a type-system trick. It is not an official API. It relies on how TypeScript evaluates intersections and call signatures. If you use this in a library, test it across different TypeScript versions.

Sometimes the weird parts of TypeScript are the most useful.

Source: https://dev.to/svs-nickm/typescript-infers-the-last-overload-so-i-changed-the-order-3018