Typescript从返回回调函数值创建一个动态元组

时间:2019-07-09 16:25:26

标签: typescript

我具有以下功能:

    class A<S> {
      data?: S;

      getSomething<R extends ((data: S) => R)>(...funcs: ((data: S) => R)[]): ReturnType<R>[] {
         return <any>funcs.map(f => {
            return f(this.data as S);
         });
      }
    }

const a = new A<{ id: number, name: string }>();
const arr = a.getSomething(data => data.name, data => data.id);

值的类型为unknown[]。如何根据返回回调值将其更改为动态?因此,在上述情况下,我希望类型为[数字,字符串]。

1 个答案:

答案 0 :(得分:3)

首先,您的类型参数应该是这些函数的数组。这将使您能够将传入的箭头函数的类型捕获为函数元组。然后,我们可以使用映射类型将元组映射到适当的返回类型。

type ReturnTypes<T extends Array<(...a: any[]) => any>> = {
    [P in keyof T]: T[P] extends (...a: any[]) => infer R ? R : never
}
class A<S> {
    data?: S;

    getSomething<R extends Array<((data: S) => any)>>(...funcs: R): ReturnTypes<R> {
        return <any>funcs.map(f => {
            return f(this.data as S);
        });
    }
}

const a = new A<{ id: number, name: string }>();
const arr = a.getSomething(data => data.name, data => data.id); //[string, number]

修改

您还可以使用数组作为参数,但是您需要稍微更改约束条件才能使编译器推断出元组类型:

type ReturnTypes<T extends Array<(...a: any[]) => any>> = {
    [P in keyof T]: T[P] extends (...a: any[]) => infer R ? R : never
}
class A<S> {
    data?: S;

    getSomething<R extends [(data: S) => any] | Array<(data: S) => any>>(funcs: R): ReturnTypes<R> {
        return <any>funcs.map(f => {
            return f(this.data as S);
        });
    }
}

const a = new A<{ id: number, name: string }>();
const arr = a.getSomething([data => data.name, data => data.id]); //[string, number]