Al tener varias funciones, me gustaría no llamarlas si no hay necesidad (lógica en needToCalculate ), usadas por una función genérica calculateIfNeeded
// helper functions function sum(a: number, b: number) { return a + b; } // complex real logic (CRL) function bum(a: number, code: string) { return (code=="B") ? a*a : a+a; } // CRL function zum(code: string) { return (code=="Z") ? 5 : 8; } // CRL function needToCalculate(code: string) {return false} // CRL Pregunta: ¿Qué tipo debe tener la func del método de abajo " calculateIfNeeded "?
// calculator function function calculateIfNeeded(code: string, func: ???, ...args: any[]){ return needToCalculate(code) ? func(args): NaN } // main function let a = 4, b = 9 let res = calculateIfNeeded("A", sum, a, b); console.log(res); res = calculateIfNeeded("B", bum, a, "B"); console.log(res); res = calculateIfNeeded("C", zum, "Z"); console.log(res);dado que parece que puede devolver cualquier cosa del cálculo (suponiendo que no esté limitado por ninguna restricción), el tipo de func será
func: (...args: any[]) => any Eso significa que esperaba recibir en func cualquier número de argumentos con cualquier tipo, y esperar regresar de func cualquier tipo.
EDITAR (inspirado en el comentario de @Dima Parzhitsky ):
Puedes hacer algo como esto:
function calculateIfNeeded<F extends any[]>(code: string, func: (...args: F)=>number, ...args: F) : number{ return needToCalculate(code) ? func(...args): NaN } Defina F como una extensión de cualquier argumento ( any[] ).
Luego, la func recibe F y devuelve any , y los argumentos mismos también son F
Entonces simplemente llamas a func(...args)
Ampliando mi comentario, tendrá que agregar un tipo de parámetro, restringirlo al tipo de función que desea usar como func e inferir el tipo de args a partir de eso:
/** * This represents not just _any function_, but one that can be * given as the second parameter (`func`) of `calculateIfNeeded`. * The call signature must be added explicitly, because apparently * TypeScript cannot know, that a union of callables is also callable */ type Func = (typeof sum | typeof bum | typeof zum) & ((...args: never[]) => number); function calculateIfNeeded<F extends Func>(code: string, func: F, ...args: Parameters<F>): number { return needToCalculate(code) ? func(...args): NaN; } Tenga en cuenta que tuve que cambiar func(args) a func(...args) , porque args es una matriz, pero ninguno de sum , bum o zum acepta una matriz como argumento.