Typescript选择仅从重载中选择特定方法(以传递给Parameters<T>)

9

背景

我遇到了一个问题,无法从一个重载的函数中获取特定参数。例如:

// someLib.d.ts
type Component<T> = {};
type A = {};
type B = {};
type C = {};
type Opts = {};
type ModernOpts = {};

export declare function mount(component: A, options: Opts): Component<A>;
export declare function mount(component: B, options: Opts): Component<B>;
export declare function mount(component: C, options: ModernOpts): Component<C>;

问题是,但我在另一个文件上这样做时:
import { mount } from 'someLib';

type specificMountParams = Parameters<typeof mount>;

我得到的参数是[C,ModernOpts],似乎没有办法获取[A,Opts][B,Opts]参数。

问题

是否有任何方法可以从重载函数中检索特定参数?(因此我可以获取[A,Opts]参数)

限制和信息

这些类型(A,B,Opts)未由库导出,我需要创建一个函数来执行类似操作所需的此类类型。


这是完全可能的,而且这个问题很可能被标记为重复。解决方案在这里:https://dev59.com/lVQJ5IYBdhLWcg3w8qpf - Kyle
@Kyle首先,上面的解决方案专门针对ReturnType有效,并且其次,它将结果合并为联合类型。我想要的是仅保留/选择其中一个重载函数。也许根据你的参考,我们可以将其转换为返回元组而不是联合类型,并选择[0-x]索引,但可能仍然不准确。 - akasection
1个回答

3
文档中得知:

当从具有多个调用签名的类型中推断出类型(例如重载函数的类型)时,推断将从最后一个签名进行(这通常是最宽泛的 catch-all 情况)。无法根据参数类型列表执行重载解析。

考虑以下示例:
function foo(a: number): number
function foo(a: string): string // last signature
function foo(a: number | string): number | string {
  return null as any
}

type Fn = typeof foo

// returns last overloaded signature
type Arguments = Parameters<Fn> // [a: string]

Parameters 总是返回函数最后一个重载签名。

尝试更改顺序:

function foo(a: string): string 
function foo(a: number): number// last signature
function foo(a: number | string): number | string {
  return null as any
}

type Fn = typeof foo

// returns last overloaded signature
type Arguments = Parameters<Fn> // [a: number]

无法返回所有参数的联合类型,因为这是不稳定的。请参见官方说明

It's not really possible to make this in a way that's both useful and sound. Consider a function like

declare function fn(n1: number, n2: number): void;

declare function doCall<T extends (a1: any, a2: any) => void>(func: T,
a0: Parameters<T>[0], a1: Parameters<T>[1]): void; ```

如果Parameters<T>[0]返回string | number,那么doCall(fn, 0, "")将会错误地成功。如果Parameters<T>[0]>返回string & number,那么doCall(fn, 0, 0)将会错误地失败(并且是一个重大的破坏性变更)。值得注意的是,使用条件类型和联合类型,真正不能用单个重载类型来表示的函数,都会有这种错误模式。

当前行为至少使一些调用被正确接受。

您可以在上述Github线程中找到一些解决方法。


3
如果联合类型不可行,我有点理解,但是可以提取/选择特定的重载函数(参数和返回类型),而跳过联合过程据说仍然是“正确”的...但是我明白这有点限制。只是有点遗憾,我不能从另一个函数中重新创建一个完全类型化的函数... - akasection

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接