【问题标题】:Is there a way to dynamically type a function in a wrapped function in Typescript?有没有办法在 Typescript 的包装函数中动态键入函数?
【发布时间】:2019-08-01 23:20:42
【问题描述】:

假设我有一个简单的用例 - 我希望将一个函数包装在另一个时间跟踪函数中。我不想在任何地方复制粘贴我的时间跟踪代码,而是通过在我的原始函数周围创建一个包装函数并因此创建一个新函数来抽象时间跟踪代码。所以我最终得到了如下函数。

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};
}

然后要使用它,我会执行以下操作:

//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);

我的问题是:有没有办法以 Typescript 可以检测错误的方式动态设置返回的 .execute() 的函数参数,并且 IDE 可以获取函数参数。

在当前状态下,如果不检查函数的生成位置,我无法检查应该传递给 .execute() 的参数。

【问题讨论】:

  • 感谢您的回复!不幸的是,这不允许我的 IDE 获取函数参数,但它确实像我想要的那样强制输入!不确定 IDE 是否可行 - 但这已经足够接近了!

标签: javascript typescript function types metaprogramming


【解决方案1】:

是的,使用泛型函数类型:

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?
}

【讨论】:

  • 我会犹豫是否直接使用F,这意味着任何额外的属性都保留在execute 中,而它们不是。您仍然可以使用此解决方案,但使用ReturnTypeParameters 构建一个不包含F 任何额外属性的签名
  • @titian 是肯定的,但我认为这将是矫枉过正
  • 我猜这取决于使用情况,但由于 typescript 现在允许我们直接将事物分配给函数并将这些事物直接广告到函数类型,它最终可能会导致混乱..
【解决方案2】:

您可以在其余参数中使用泛型和元组:

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

【讨论】:

    猜你喜欢
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 2022-01-26
    • 2012-10-11
    相关资源
    最近更新 更多