Typescript:键入一个带有函数数组的函数,该数组返回每个函数返回类型的数组



是否可以正确键入以下代码?

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[]

设法用完成

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] )

谢谢大家的帮助!!

我对它能否正确键入并不乐观。首先,我认为您看到的是元组,而不是数组,因为";阵列";的函数具有不同的签名,并且您希望arrayElementTypes的返回类型对应于"中每个函数的返回类型;阵列";,匹配位置

同时,我不太愿意直接说这是不可能的,因为我已经看到了使用泛型和条件类型的组合可以完成的惊人的事情。


编辑:我想出了一些";构建块";可能有助于最终答案的类型,但你可以看看是否可以将它们拼凑在一起:(

// 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[]
const [varA, varB, varC, varD]: Array<string | number | {prop: string} | number[]> = arrayElementTypes( () => "", () => ({prop: "prop"}), () => [1,2,3] )

这符合你的要求吗?

最新更新