Есть ли способ динамического ввода функции в упакованную функцию в Typescript? - PullRequest
1 голос
/ 11 марта 2019

Скажем, у меня есть простой вариант использования - я хочу, чтобы функция была включена в другую функцию отслеживания времени. Вместо того, чтобы копировать и вставлять мой код отслеживания времени везде, я хочу абстрагировать код отслеживания времени, создавая функцию-обертку вокруг моей исходной функции и в результате создавая новую функцию. В итоге я получаю функцию, подобную следующей.

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

У меня вопрос: есть ли способ динамически установить параметры функции возвращаемого .execute () таким образом, чтобы Typescript мог обнаруживать ошибки, а интегрированные среды разработки могли выбирать параметры функции.

В текущем состоянии у меня нет возможности проверить, какие параметры я должен передавать в .execute (), не проверяя, где была сгенерирована функция.

Ответы [ 2 ]

3 голосов
/ 11 марта 2019

Вы можете использовать дженерики и кортежи в аргументах остальных:

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 голосов
/ 11 марта 2019

Да, используйте универсальный тип функции:

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