重载函数的通用参数并不包含所有选项

重载函数的通用参数并不包含所有选项

问题描述:

给出一个重载的函数example.

Given an overloaded function example.

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

type Result = Parameters<typeof example>

我希望Result包含example参数的所有选项,而不仅仅是第一个/最顶部的参数集.如何获取参数?

I'd expect Result to contain ALL options for arguments of example, not just the first / top-most argument set. How can I get the parameters?

的答案中问题是否重复 @ ford04的答案中提到的限制,infer仅查看最后一个重载签名,被确认.

In the answers to the question this duplicates the limitation mentioned in @ford04's answer here, that infer only looks at the last overloaded signature, is acknowledged.

但是此答案表明并非完全是不可能的;您可以从中获取一些有关重载的信息,至少对于具有最多任意固定数量重载的函数而言.但这是多毛且丑陋的,并且其中可能有错误,请参阅microsoft/TypeScript#28867 .这是一种实现方法:

But this answer shows it's not completely impossible; you can tease out some information about overloads, at least for functions with up to some arbitrary fixed number of them. But it's hairy and ugly and there might be bugs in it, see microsoft/TypeScript#28867. Here's one way of doing it:

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

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

The Overloads<T> type alias takes a function type T and returns a tuple of its call signatures (for up to four overloads). And OverloadedParameters<T> and OverloadedReturnType<T> map Parameters<T> and ReturnType<T> over that tuple, respectively.

让我们看看它的作用(在更正示例之后,如在另一个答案中所做的那样,它实际上具有多个重载):

Let's see it in action (after correcting your example so that it actually has multiple overloads, as done in the other answer):

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]]

对我来说合理.好的,希望能有所帮助;祝你好运!

Looks reasonable to me. Okay, hope that helps; good luck!

链接到代码