网站搜索

TypeScript 函数参数泛型


我正在尝试创建一个 TypeScript 函数,它接受一个数组并返回一个新函数,其中参数具有数组的类型。

换句话说,它应该像这样:

type MyFunc = {
    <A>(arg: [A]): ((arg0: A) => any)
    <A, B>(arg: [A, B]): ((arg0: A, arg1: B) => any)
    <A, B, C>(arg: [A, B, C]): ((arg0: A, arg1: B, arg2: C) => any)
}

但是对于可变数量的输入

具体例子

这里有一些具体的例子(尽管我在寻找一般情况):

type MyFuncA = (arg: [number]) => ((arg0: number) => any)
type MyFuncB = (arg: [string]) => ((arg0: string) => any)
type MyFuncC = (arg: [number, string]) => ((arg0: number, arg1: string) => any)
type MyFuncD = (arg: [number, string, bool]) => ((arg0: number, arg1: string, arg2: bool) => any)

答案#1

我认为最简单的方式是:

type MyFunc = <T extends readonly unknown[]>(args: T) => (...args: T) => unknown

它接受一个任意类型的数组作为 T,并使用 ...args: T 将该数组展开到返回函数的参数中。

用法:

declare const fn: MyFunc // pretend this function exists

const testA = fn([1, 'asd', true] as const)
// (args_0: 1, args_1: "asd", args_2: true) => unknown

只需注意这里使用了 as const 来强制将参数设为元组类型 [number, string, boolean],而不是数组类型 (number | string | boolean)[],因为它需要通过元组来推断参数的顺序。但提供任何元组类型都应该可以正常工作。

如果你没有传入元组,你将提供一个展开数组类型,这比什么都没有要好,但没有那么有用:

const testA = fn([1, 'asd', true])
// (...args: (string | number | boolean)[]) => unknown

操场


如果你有一个为每个元素命名的元组类型,这些名字甚至会作为函数的参数名被报告!

const myTuple: [num: number, str: string, isAwesome: boolean] = [1, 'asd', true]
const testA = fn(myTuple)
// (num: number, str: string, isAwesome: boolean) => unknown

这很整洁。

操场