TypeScript Tidbit: How to Overload an Imported Function
November 20, 2020 - 5 min
There are times when the type definitions shipped on DefinitelyTyped are not enough and this results in making the TypeScript compiler unhappy. Oh noes! 😭
Overload an imported function in TypeScript
But fear not! It is possible to overload a function imported from a different module (which could even be a local module/file, not necessarily a node module) without “patching” the corresponding @types/<package>
type definitions.
import { someFunction } from 'module'
// the function overloading
declare module 'module' {
function someFunction() // the overload you need
}
someFunction() // with the overloaded version ✔️
Example: overload Ramda’s compose
function
A practical example is Ramda’s compose
function. If you pass more than 7 functions to the function, you need to overload Ramda’s type definitions coming from @types/ramda
as the TypeScript compiler will report an error otherwise (TypeScript Playground Error Example).
DefinitelyTyped obviously cannot provide the type definitions for any number of arguments as compose
accepts as many arguments as you want. So it’s up to you to inform the TypeScript compiler that this usage is actually okay. 😌
This can be done like in the example below (TypeScript Playground Working Example):
import * as R from 'ramda'
// overloading compose because `@types/ramda` exposes types for up to 6 functions
declare module 'ramda' {
function compose<V0, T1, T2, T3, T4, T5, T6, T7>(
fn6: (x: T6) => T7,
fn5: (x: T5) => T6,
fn4: (x: T4) => T5,
fn3: (x: T3) => T4,
fn2: (x: T2) => T3,
fn1: (x: T1) => T2,
fn0: (x0: V0) => T1
): (x0: V0) => T7
}
// and now, we can use:
const someComplicatedResult = R.compose<V0, T1, T2, T3, T4, T5, T6, T7>(
fn6,
fn5,
fn4,
fn3,
fn2,
fn1,
fn0
)('😅')
We can see from the screenshot below that the overload was correctly taken into consideration. 🎉
Caveat
I can imagine that if this is overused, things can become quickly intractable. So use it sparingly and always with a good reason why. Your future self will be happy to find an explanation in a comment above the overloading as it is kind of unusual. 😉
I discovered this while refactoring @kiwicom/splitster
to TS (link to commit) and thought it might be useful to share. Hope it helped you!
Personal blog written by Robin Cussol
I like math and I like code. Oh, and writing too.