簡體   English   中英

有條件地調用帶有參數的函數

[英]conditionally call a function with its params

有幾個函數,如果不需要(邏輯需要在需要needToCalculate ),我不想調用它們,由通用函數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

問題:下面的方法calculateIfNeeded的param func應該是什么類型?

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

操場

因為看起來你可以從計算中返回任何東西(假設你不受任何限制), func的類型將是

func: (...args: any[]) => any

這意味着您希望在func中接收任意數量的任何類型的參數,並希望從func返回任何類型。

編輯(受@Dima Parzhitsky評論啟發):

你可以這樣:

function calculateIfNeeded<F extends any[]>(code: string, func: (...args: F)=>number, ...args: F) : number{
    return needToCalculate(code) ? func(...args): NaN
}

F定義為任何參數( any[] )的擴展。

然后func接收F並返回any ,並且 args 本身也是F

然后你只需調用func(...args)

根據我的評論,您將不得不添加一個參數類型,將其限制為您要用作func的函數的類型,並從中推斷出args的類型:

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

試試看

請注意,我必須將func(args)更改為func(...args) ,因為args是一個數組,但sumbumzum都不接受數組作為參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM