打字稿:使用函数数组输入函数,该函数返回每个函数返回类型的数组
Posted
技术标签:
【中文标题】打字稿:使用函数数组输入函数,该函数返回每个函数返回类型的数组【英文标题】:Typescript: typing a function with an array of functions that returns an array of each function return type 【发布时间】:2021-07-05 18:49:52 【问题描述】:下面的代码可以输入正确吗?
function arrayElementTypes(...array: Array<(() => string) | (() => number) | (() => prop: string) | (() => number[])>)
/// .. do something
/// .. and then return an array with each functions result
return array.map(arg => arg())
const [varA, varB, varC] = arrayElementTypes( () => "", () => (prop: "prop"), () => [1,2,3] )
// how can this be typed appropriately so that the :
// varA: string
// varB: prop: string
// varC: number[]
【问题讨论】:
很难知道“输入正确”是什么意思。您正在传递一组具有不同参数计数的函数,因此array.map(arg => arg())
对于数组联合中的最后一个函数类型无效。您也只传入 3 个函数,但正在寻找一个长度为 4 的返回数组。您是否希望将返回的数组解构为单独的类型(好像它是一个元组)或函数的返回类型的交集(好像它是一个数组)?
更正了示例。
【参考方案1】:
设法做到了
type ReturnTypes<T extends Array<(...a: any[]) => any>> =
[P in keyof T]: T[P] extends (...a: any[]) => infer R ? R : never
type CustomArrayElement = (() => string) | (() => number) | (() => prop: string) | (() => number[])
function arrayElementTypes<T extends CustomArrayElement[]>(...array: T): ReturnTypes<typeof array>
return array.map(arg => arg())
const [varA, varB, varC] = arrayElementTypes( () => "", () => (prop: "prop"), () => [1,2,3] )
谢谢大家的帮助!!
【讨论】:
【参考方案2】:我不乐观它可以正确输入。首先,我认为您正在查看 tuple,而不是数组,因为函数的“数组”具有不同的签名,并且您希望 arrayElementTypes
的返回类型对应于返回类型“数组”中的每个函数,匹配 position-wise.
同时,我不敢说完全不可能,因为我已经看到 amazing things 可以使用泛型和条件类型的组合来完成。
编辑:我想出了一些可能有助于最终答案的“构建块”类型,但您可以看看是否可以将它们拼凑在一起:)
// any function
type Fn = () => unknown;
// a tuple/array of functions
type FnArr = readonly Fn[];
// the first function in your tuple of functions
type Head<T extends FnArr> = T extends [infer HeadFn, ...any[]] ? HeadFn : never;
// the rest of the functions in your tuple of functions
type Tail<T extends FnArr> = T extends [any, ...infer TailFns] ? TailFns : never;
使用上述构建块,您可以提取函数元组中每个函数的返回类型。这并不直接适用于解决方案,但也许一些递归定义的条件类型(泛化为任意函数元组)可以让你到达那里:)
const [varA, varB, varC] = arrayElementTypes( () => "", () => (prop: "prop"), () => [1,2,3] )
// how can this be typed appropriately so that the :
// varA: string
// varB: prop: string
// varC: number[]
type ExampleFns = [ () => string, () => prop: "prop", () => number[] ];
type TypeForVarA = ReturnType<Head<ExampleFns>>; // F1 = string
type TypeForVarB = ReturnType<Head<Tail<ExampleFns>>>; // F2 = prop: "prop"
type TypeForVarC = ReturnType<Head<Tail<Tail<ExampleFns>>>>; // F3 = number[]
【讨论】:
【参考方案3】:const [varA, varB, varC, varD]: Array<string | number | prop: string | number[]> = arrayElementTypes( () => "", () => (prop: "prop"), () => [1,2,3] )
这是否满足您的要求?
【讨论】:
以上是关于打字稿:使用函数数组输入函数,该函数返回每个函数返回类型的数组的主要内容,如果未能解决你的问题,请参考以下文章