Is there a way to dynamically type a function in a wrapped function in Typescript?

问题: So say I have a simple use case - I want a function to be wrapped in another time tracking function. Rather than copy-paste my time tracking code everywhere I want to abstr...

问题:

So say I have a simple use case - I want a function to be wrapped in another time tracking function. Rather than copy-paste my time tracking code everywhere I want to abstract the time tracking code by creating a wrapper function around my original function and creating a new function as a result. So I end up with a function like the following.

function wrapFunction(someFunction: Function) {
  const wrappedFunction = function() {
    let args = arguments;
    let beforeTime = new Date();
    someFunction.apply(args);
    let afterTime = new Date();
    console.log("Time Elapsed " + afterTime - beforeTime);
  };
  return {execute: wrappedFunction};
}

Then to use it I would do something like the following:

//Generate the wrapped function
let wrappedFunction = wrapFunction((param1 : string, param2: number) =>{
  console.log("Param1 = ", param1);
  console.log("Param2 = ", param2);
});
//This is the actual usage of the function
wrappedFunction.execute('param1', 2);

My question is: is there a way to dynamically set the function parameters of that returned .execute() in a way that Typescript can detect errors, and IDEs can pick up on the function parameters.

In the current state, I have no way to check what parameters I should be passing into .execute() without checking where the function was generated.


回答1:

You can use generics and tuples in rest arguments:

function wrapFunction<A extends any[], R>(someFunction: (...a: A) => R) {
    const wrappedFunction = function (...args: A) {
        let beforeTime = new Date();
        let result = someFunction(...args);
        let afterTime = new Date();
        console.log("Time Elapsed " + (afterTime.getDate() - beforeTime.getDate()));
        return result;
    };
    return { execute: wrappedFunction };
}

//Generate the wrapped function
let wrappedFunction = wrapFunction((param1: string, param2: number) => {
    console.log("Param1 = ", param1);
    console.log("Param2 = ", param2);
});

wrappedFunction.execute('param1', 2); //ok now

回答2:

Yup, use a generic function type:

function wrapFunction<F extends Function>(someFunction: F) {
  function wrappedFunction(...args) { // personal preference + performance boost
    const beforeTime = new Date();
    const result = someFunction.apply(this, args);
    const afterTime = new Date();
    console.log("Time Elapsed " + afterTime - beforeTime);
    return result;
  }

  return {execute: wrappedFunction as F }; // why this object though?
}
  • 发表于 2019-03-12 19:32
  • 阅读 ( 179 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除