重载函数的参数泛型不包含所有选项

Tho*_*ggi 9 generics parameters typescript

给定一个重载函数example

function example(a: string): number
function example(a: string, b?: string): number { 
  return 1
}

type Result = Parameters<typeof example>
Run Code Online (Sandbox Code Playgroud)

我希望 Result 包含 参数的所有选项example,而不仅仅是第一个/最顶层的参数集。我怎样才能得到参数?

jca*_*alz 10

在问题的答案中,这重复了@ford04的答案中提到的限制,即infer只查看最后一个重载的签名,这是公认的。这是 TypeScript 缺失的功能或设计限制;有关相关功能请求,请参阅microsoft/TypeScript#29732 。

这个答案表明这并非完全不可能;您可以梳理出一些有关重载的信息,至少对于具有任意固定数量的函数(从 TypeScript 4.8 开始仍然如此;递归条件类型没有帮助)。但它又丑又毛茸茸的,而且可能存在错误,请参阅 microsoft/TypeScript#28867。这是一种方法:

type Overloads<T> =
  T extends {
    (...args: infer A1): infer R1;
    (...args: infer A2): infer R2;
    (...args: infer A3): infer R3;
    (...args: infer A4): infer R4
  } ? [
    (...args: A1) => R1,
    (...args: A2) => R2,
    (...args: A3) => R3,
    (...args: A4) => R4
  ] : T extends {
    (...args: infer A1): infer R1;
    (...args: infer A2): infer R2;
    (...args: infer A3): infer R3
  } ? [
    (...args: A1) => R1,
    (...args: A2) => R2,
    (...args: A3) => R3
  ] : T extends {
    (...args: infer A1): infer R1;
    (...args: infer A2): infer R2
  } ? [
    (...args: A1) => R1,
    (...args: A2) => R2
  ] : T extends {
    (...args: infer A1): infer R1
  } ? [
    (...args: A1) => R1
  ] : any

type OverloadedParameters<T> =
  Overloads<T> extends infer O ?
  { [K in keyof O]: Parameters<Extract<O[K], (...args: any) => any>> } : never

type OverloadedReturnType<T> =
  Overloads<T> extends infer O ?
  { [K in keyof O]: ReturnType<Extract<O[K], (...args: any) => any>> } : never
Run Code Online (Sandbox Code Playgroud)

类型Overloads<T>别名采用函数类型T并返回其调用签名的元组(最多四个重载)。并分别映射该元组上的OverloadedParameters<T>和。OverloadedReturnType<T>Parameters<T>ReturnType<T>

让我们看看它的实际效果(在更正您的示例之后,使其实际上具有多个重载,如其他答案中所做的那样):

function example(a: string): number
function example(a: string, b: string): number
function example(a: string, b?: string): number {
  return 1
}

type ExampleOverloads = Overloads<typeof example>
// type ExampleOverloads = [(a: string) => number, (a: string, b: string) => number]

type ExampleParameters = OverloadedParameters<typeof example>
// type ExampleParameters = [[string], [string, string]]
Run Code Online (Sandbox Code Playgroud)

对我来说看起来很合理。好的,希望有帮助;祝你好运!

链接到代码