2017-06-21 69 views
1

假設我們有一個接受可變數量參數的函數,我相信它被稱爲可變參數函數。帶TypeScript的變量參數 - 強制最後一個參數

事情是這樣的:

function foo(){ 
let args = Array.from(arguments).map(v => whatever); 
    // do something with args 
} 

此功能的打字稿接口可能看起來像:

interface IVariadicFn { 
    (...args: string[]): void, 
} 

但是我們要說,我們期待一個可變數量的字符串,但最終的參數,我們預計成爲回調函數。

所以我們希望有這樣的事情:

function variadic(){ 
let args = Array.from(arguments) 
let fn = args.pop(); 
let $args = args.map(v => whatever); 
    // do something with args 
process.nextTick(function(){ 
    fn(null, $args); // fire the callback, asynchronously 
}); 
} 

有聲明此功能的打字稿定義的方法嗎?

我現在能做的最好的是這樣的:

type IVariadicArgs = string | Function; 

export interface IBeforeFn { 
    (...args: IVariadicArgs[]): void; 
} 
+1

見https://github.com/Microsoft/TypeScri pt/issues/1336 – kemsky

+1

討論目前似乎已轉移到[#5453](https://github.com/Microsoft/TypeScript/issues/5453)。 – Tycho

+0

*這個關於靜態檢查falsy參數/空字符串的問題真的很好* –

回答

2

沒有,像你想你不能這樣做,但你可以通過第一個參數的函數,那麼最後的。也不要使用arguments。你可以用rest參數

interface IVariadicFn { 
    (func: Function, ...args: string[]): void, 
} 

function foo(func: Function, ...args: string[]){ 
    let arguments = Array.from(args).map(v => whatever); 
    // do something with arguments 
} 

代替這一點,你可以調用像

foo(yourFunc, 'asd', 'bsd', 'csd'); 
+0

你可以舉一個使用rest參數的例子嗎?我不知道你的意思。 –

+0

是不是你的榜樣提示func在列表中排在第一位?我需要它最後。 –

+0

@AlexanderMills如果您對最後一個項目沒有任何要求,那麼因爲'rest'參數必須是最後一個參數,請首先使用它。而且,接受兩種類型的參數並不是一個好習慣 –

1

雖然你不能做到這一點,一般,你可以定義多個重載應覆蓋大多數的使用案例:

function variadic(fn:() => void) 
function variadic(a: string, fn:() => void) 
function variadic(a: string, b: string, fn:() => void) 
function variadic(a: string, b: string, c: string, fn:() => void) 
function variadic(a: string, b: string, c: string, d: string, fn:() => void) 
function variadic(...args: (string | (() => void))[]) { 
    // ... 
} 

variadic(() => 3, "foo") // error 
variadic("foo",() => 3) // ok 
variadic("foo", "bar",() => 3) // ok 

playground