2017-06-21 45 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