javascript - ¿Hay alguna manera de tipar dinámicamente una función en una función envuelta en Typescript?
Entonces digamos que tengo un caso de uso simple: quiero que una función sea envuelta en otra función de seguimiento de tiempo. En lugar de copiar y pegar mi código de seguimiento de tiempo por todas partes, quiero abstraer el código de seguimiento de tiempo creando una función envolvente alrededor de mi función original y creando una nueva función como resultado. Así que termino con una función como la siguiente.
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};
}
Luego, para usarlo, haría algo como lo siguiente:
//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);
Mi pregunta es: ¿hay una forma de establecer dinámicamente los parámetros de la función de ese .execute() devuelto de manera que Typescript pueda detectar errores y los IDE puedan identificar los parámetros de la función?
En el estado actual, no tengo manera de verificar qué parámetros debería pasar a .execute() sin comprobar dónde se generó la función.
Respuesta #1
Puedes usar genéricos y tuplas en los argumentos rest:
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
Respuesta #2
Sí, usa un tipo de función genérica:
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?
}
