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

Posted

技术标签:

【中文标题】打字稿仅从重载中选择特定方法(要传递给Parameters<T>)【英文标题】:Typescript pick only specific method from overload (to be passed to Parameters<T>) 【发布时间】:2021-10-18 07:01:41 【问题描述】:

背景

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

// 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) 没有被库导出,我需要创建一个需要这种类型的函数来做类似的事情。

【问题讨论】:

【参考方案1】:

来自docs:

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

考虑这个例子:

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]

没有办法返回所有参数的联合,因为它是不健全的。 见官方解释here

真的不可能以一种既有用又合理的方式来制作它。考虑一个类似

的函数
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&lt;T&gt;[0] 返回string | number,则doCall(fn, 0, "") 会错误地成功。如果Parameters&lt;T&gt;[0]&gt; 返回string &amp; number,那么doCall(fn, 0, 0) 将错误地失败(并且是一个大 突破性变化)。值得注意的是,对于条件类型和联合,真的 唯一不能用单个重载类型的函数 正是具有这种故障模式的那些。

当前的行为至少可以正确接受一些调用。

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

【讨论】:

如果联合类型是不可能的,我有点明白,但是在跳过联合过程的同时提取/选择特定的重载函数(参数和返回类型)应该仍然是声音。 ..但是是的,我知道这是一种限制。我不能从另一个函数重新创建一个完全类型化的函数,这有点令人遗憾......

以上是关于打字稿仅从重载中选择特定方法(要传递给Parameters<T>)的主要内容,如果未能解决你的问题,请参考以下文章

打字稿编译器选择错误的重载

Python - 如何传递给类对象的函数参数类型(打字)

从 makeStyles 切换到 mui5 sx 道具-打字稿错误(没有重载匹配此调用)传递具有位置的对象

如何知道用户是不是正在打字或消息是不是已在聊天应用程序中传递给他

如何将成员函数指针传递给模板函数中的重载方法?

使用特定日期填充 jQuery Datepicker