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

aka*_*ion 9 parameters methods overloading utility typescript

背景

所以我在从重载的函数获取特定参数时遇到问题。例如:

// 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>;
Run Code Online (Sandbox Code Playgroud)

问题是,如果我在另一个文件上执行此操作:

import { mount } from 'someLib';

type specificMountParams = Parameters<typeof mount>;
Run Code Online (Sandbox Code Playgroud)

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

问题

有没有办法从重载函数中检索特定参数?(这样我就可以获取[A, Opts]参数)

限制和信息

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

cap*_*ian 3

来自文档

当从具有多个调用签名的类型(例如重载函数的类型)进行推断时,将从最后一个签名进行推断(这可能是最允许的包罗万象的情况)。无法根据参数类型列表执行重载决策。

考虑这个例子:

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]
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

无法返回所有参数的并集,因为它不健全。官方解释请看这里

以一种既有用又合理的方式来实现这一点实际上是不可能的。考虑一个像这样的函数

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; ```

Run Code Online (Sandbox Code Playgroud)

如果Parameters<T>[0]返回string | number,则将doCall(fn, 0, "") 错误地成功。如果Parameters<T>[0]>返回string & numberdoCall(fn, 0, 0)则将错误地失败(并且是一个重大的重大更改)。值得注意的是,对于条件类型和联合,实际上唯一不能使用单个重载键入的函数正是具有这种故障模式的函数。

目前的行为至少使得一些呼叫能够被正确接受。

您可以在上面的 github 线程中找到一些解决方法

  • 如果联合类型不可能,我有点明白,但是在跳过联合过程的同时提取/选择特定的重载函数(参数和返回类型)据说仍然是_sound_...但是,是的,我明白这是一种限制。只是有点遗憾我无法从另一个函数重新创建完全类型化的函数...... (3认同)