TypeScript含可选参数的函数重载与剩余参数兼容问题求助
TypeScript 函数重载的可选参数处理问题
我在TypeScript里写函数重载时,习惯用这种模式:
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]类型,面对复杂类型时能大幅简化内部逻辑。
但碰到可选参数时,这套模式就失效了:
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类型时,剩余参数的类型是确定的,但上面的写法还是会报错。如果枚举所有参数排列会产生大量变体,而合并参数类型又不得不处理那些逻辑上不可能存在的组合。有没有可行的解决办法?
内容的提问来源于stack exchange,提问作者ext
相关产品推荐
相关产品推荐

