【问题标题】:Excluding function parameters by type in TypeScript在 TypeScript 中按类型排除函数参数
【发布时间】:2020-11-25 08:50:29
【问题描述】:

我希望能够采用具有 n 个参数的函数并基于该函数返回一个类型,其中任何类型为 x 的参数都不再属于函数类型。例如:

function myTestFunction(email: string, context: TestContext, password: string): void {
  ...
}

我想要一个类型来使用它来创建这样的函数定义:

function myTestFunction(email: string, password: string): void {
  ...
}

我已经设法做到了:

type Filter<T> = T extends [] 
  ? [] 
  : T extends [infer A, ...infer B] 
    ? A extends TestContext 
      ? Filter<B>
      : [A, ...Filter<B>]
    : T;
type ConvertFunction<T> = T extends (...args: any[]) => any
  ? (...args: Filter<Parameters<T>>) => ReturnType<T>
  : T;

唯一的问题是参数名丢失,签名变成:

function myTestFunction(args_0: string, args_1: string): void {
  ...
}

请问如何在不丢失参数名称的情况下做到这一点?

【问题讨论】:

  • 您使用的是哪个版本的打字稿? IIRC有改进w.r.t。这在 TS4+ 中
  • 我使用的是 TS v4.1.2。
  • 我会将context 更改为第一个参数(无论如何似乎更合乎逻辑)并使用此答案:stackoverflow.com/a/58765199/1517969

标签: typescript conditional-types


【解决方案1】:

嗯,我认为你做不到。

你可以做的是传播一个元组来保存名字

type MyTup = [a: string, b: number]
type MyTup2 = [...MyTup] // [a: string, b: number]

但是,当您从元组中获取单个值时,它将失去其名称。

type MyTup = [a: string, b: number]
type MyTup2 = [MyTup[0], MyTup[1] // [string, string]

如果你将一个未命名的成员与一个命名的元组合并,所有的成员都会变成未命名的:

type MyTup = [a: string, b: number]
type B = [MyTup[0], ...MyTup] // [string, string, string]

当然,您可以重新添加名称,但我不知道实际获取元组成员的名称。所以一般来说没有办法做到这一点。

type B = [asdf: MyTup[0], qwerty: MyTup[1]] // [asdf: string, qwerty: string]

这意味着当你这样做时:

[A, Filter<B>]

然后你正在生成一个未命名的元组。而这种re-re-re-constructing tuple的递归方式是目前唯一可以通用地添加或删除tuple成员的方法。


所以我可能是错的,但我不确定当前版本的打字稿是否可行。

【讨论】:

    猜你喜欢
    • 2013-11-03
    • 2016-11-01
    • 2021-07-08
    • 2019-10-19
    • 1970-01-01
    • 2018-08-28
    • 2020-04-27
    • 2012-09-23
    • 2023-02-22
    相关资源
    最近更新 更多