在 TypeScript 中按类型排除函数参数
我希望能够接受一个具有 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 {
...
}
请问如何在不丢失参数名称的情况下做到这一点?
答案#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>]
那么你正在生成一个未命名的元组。而这种反复重新构建元组的递归方法,目前是以通用方式添加或移除元组成员的唯一方式。
所以我可能是错的,但我不确定在当前版本的 TypeScript 中这是否可行。
