Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Type something like _.once

just starting out with TS, how would I go about typing something like...

function once(fn) {
  var haveResult = false;
  var result = null;

  return (...args) => {
    if (!haveResult) {
      haveResult = true;
      result = fn.apply(this, args);
    }

    return result;
  };
}

Where once can receive a function with any params and return any. Just like lodash's _.once

like image 347
donzul Avatar asked Mar 03 '26 08:03

donzul


1 Answers

You could use a generic parameter for the function type, and return a new function with the same type. Unfortunately since you can't have a variable number of type parameters for each parameter, you will need to use a type assertion to get the helper function to match the result type, but the call site will infer everything correctly:

function once<TFunction extends (...args: any[])=> any>(fn: TFunction): TFunction {
    var haveResult = false;
    var result: any = null;

    return (function (this: any, ...args: any[]) {
        if (!haveResult) {
            haveResult = true;
            result = fn.apply(this, args);
        }

        return result;
    }) as any;
}
// Usage 
class Test {
    doStuff (t: string){
        console.log('doStuff');
        return  1;
    }

    constructor() {
        this.doStuff = once(this.doStuff);
    }
}

let t = new Test();
t.doStuff('s');
t.doStuff('s');
like image 61
Titian Cernicova-Dragomir Avatar answered Mar 05 '26 23:03

Titian Cernicova-Dragomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!