Search code examples
javascripttypescripttypescript-typingsstrong-typing

How to add typings for a function wrapper in TypeScript?


I am trying to write a small cache wrapper in typescript (simplified pseudo demo code):

const cache = {};
export function cachify<T, V>(name:string, getFunction: (i:V)=>Promise<T>): (i:V) => Promise<T> {
  return function() {
    return cache[name] || getFunction.apply(this,arguments)
  }
})

This works great if my function has only one argument e.g.

function isNameFancy(name:string) {
  return Promise.resolve(true)
}
const isNameFancyWithCache = cachify(isNameFancy)

However as i specified i:V this only valid for one argument.

If I have a second function e.g. isPersonFancy it won't work:

function isPersonFancy(personAge: number, personName: string) {
  return Promise.resolve(true)
}
const isPersonFancyWithCache = cachify(isPersonFancy)

How do I have to change my cachify function types so that it works for both cases?


Solution

  • You can declare other signatures for the cachify function:

    const cache = {};
    export function cachify<T, V>(name: string, getFunction: (i: V) => Promise<T>): (i: V) => Promise<T>;
    export function cachify<T, V1, V2>(name: string, getFunction: (i: V1, j: V2) => Promise<T>): (i: V1, j: V2) => Promise<T>;
    export function cachify(name: string, getFunction: (...args: any[]) => Promise<any>): (...args: any[]) => Promise<any> {
        return function () {
            return cache[name] || getFunction.apply(this,arguments)
        }
    };
    
    function isNameFancy(name: string) {
        return Promise.resolve(true)
    }
    const isNameFancyWithCache = cachify("isNameFancy", isNameFancy); // (i: string) => Promise<boolean>
    
    function isPersonFancy(personAge: number, personName: string) {
        return Promise.resolve(true)
    }
    const isPersonFancyWithCache = cachify("isPersonFancy", isPersonFancy); // (i: number, j: string) => Promise<boolean>
    

    (code in playground)