我具有以下功能:
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[]
。如何根据返回回调值将其更改为动态?因此,在上述情况下,我希望类型为[数字,字符串]。
答案 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]