首页 > 解决方案 > 如何为具有重载签名的单个实现推断 Typescript 参数类型?

问题描述

我的call方法有两个签名和一个实现:

call<T extends CallChannel, TArgs extends CallParameters[T]>(channel: T, ...args: TArgs): ReturnType<CallListener<T>>;
call<T extends SharedChannel, TArgs extends SharedParameters[T]>(channel: T, ...args: TArgs): ReturnType<SharedListener<T>>;
call(channel, ...args) { ... }

但是 Typescript 不会进行类型检查,因为 to 的参数call是隐式类型的any。显然它们不应该是,对于第一个参数,它们必须是CallChannelorSharedChannel类型,同样,第二个参数是两个特定类型之一。

但我不能像这样定义实现:

call<T extends CallChannel | SharedChannel, TArgs extends CallParameters[T] | SharedParameters[T]> (channel: T, ...args: TArgs) {

因为类型CallParameters[T]无法解析 whenT是 a SharedChannel(反之亦然)。

我已经提供了定义所需的所有类型信息call,如何让 typescript 对实现的签名感到满意?

标签: typescriptoverloading

解决方案


您应该能够使用条件类型来做到这一点。

为 args 和 return 定义条件类型。

    type Args<T extends CallChannel | SharedChannel> = 
        T extends CallChannel 
        ? CallParameters[T] 
        : T extends SharedChannel 
        ? SharedParameters[T] 
        : never

然后更新函数以使用它:

 TArgs extends Args<T>

返回可以使用相同的原理。


推荐阅读