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
这很整洁。
操场
