在重载函数时,我有时会使用以下模式:
export function foo(a: string): void;
export function foo(b: number): void;
export function foo(a: string, b: number): void;
export function foo(...args: [string] | [number] | [string, number]): void {
/* ... */
}
这使得很容易确定使用了哪种原型,例如,如果是args.length === 2
,则已知args
是[string, number]
.对于更复杂的类型(假设您有两个接口,而不是string
和number
),这可以大大简化.
但是,在使用可选参数时,我无法使其正常工作:
export function foo(a?: string): void;
// ~~~ error TS2394: This overload signature is not compatible with its implementation signature.
export function foo(...args: [] | [string]): void {
return;
}
我知道我可以在没有可选参数的情况下简单地添加另一个重载,但组合很快就会变得无法管理.
export function foo(): void;
export function foo(a: string): void;
export function foo(...args: [] | [string]): void {
return;
}
一个更具体的例子是:
interface Foo {
/* ... */
}
interface Bar {
/* ... */
}
interface Baz {
/* ... */
}
function awesomeFunction(foo?: Foo, bar?: Bar): void;
function awesomeFunction(baz: Baz, foo?: Foo, bar?: Bar): void;
function awesomeFunction(...args:
| [Foo | undefined, Bar | undefined]
| [Baz, Foo | undefined, Bar | undefined]
): void {
/* ... */
}
因为我知道,如果args[0]
是Baz
,我也会知道args
的其余元素.然而,它不能像上面看到的foo
函数那样工作.
输入所有的排列将变成许多变体,而输入每个参数为arg1?: Foo | Baz, arg2: Foo | Bar, arg3: Bar
意味着我必须输入判断不可能的变体.
有没有办法解决这个问题?