typescript - 调用对象方法的返回类型注解
我如何为一个函数编写返回类型注解,该函数接收一个对象,调用其所有方法,并返回一个新对象,其中原始键映射到这些方法的返回值?
function callMethods<T>(obj: T) {
const objResults = {};
Object.keys(obj).forEach((prop) => objResults[prop] = obj[prop]({}));
return objResults;
}
type MethodArgs = any // some complex object
console.log(callMethods({
a: (_args: MethodArgs): number => 1,
b: (_args: MethodArgs): string => "one",
c: (_args: MethodArgs): number[] => [1]
}));
// => {a: 1, b: "one", c: [1]}
// This object's type should be {a: number, b: string, c: number[]}
答案#1
目前没有办法正确地获取方法调用的返回类型,因此我的解决方案只是部分的。不过,有一个正在进行中的提案,你可以在这里了解更多信息。
你能做到的最好就是至少从你现在拥有的东西中再多打些字出来。
你可以做的一件事是使用映射类型来获取 T 的键,并将它们作为返回值中的键。
function callMethods<T>(obj: T) {
return Object.keys(obj).reduce((previous, current) => {
previous[current] = obj[current]({});
return previous;
}, {} as {[P in keyof T]: any});
}
因为方法的返回类型无法确定,返回对象的属性的值类型将是 any。
如果返回类型是有限的,你可以将它们定义为一种类型并使用它们(这不是完美的,但可能会更好)。
type ReturnTypes = number | string | number[];
function callMethods<T>(obj: T) {
return Object.keys(obj).reduce((previous, current) => {
previous[current] = obj[current]({});
return previous;
}, {} as {[P in keyof T]: ReturnTypes});
}
如果已知返回类型和传入对象的类型,你也可以将它们作为外部参数传递,这样就可以创建一个更通用的函数。
type ReturnTypes = number | string | number[];
interface Methods {
a: (args: any) => number,
b: (args: any) => string,
c: (args: any) => number[],
}
function callMethods<T, V>(obj: T) {
return Object.keys(obj).reduce((previous, current) => {
previous[current] = obj[current]({});
return previous;
}, {} as {[P in keyof T]: V});
}
let result = callMethods<Methods, ReturnTypes>({
a: (_args): number => 1,
b: (_args): string => "one",
c: (_args): number[] => [1]
});
虽然这不是完美的解决方案,但我希望它能帮到你。
注意:请原谅方法的重写,使用 reduce 看起来更简洁。
答案#2
截至 [email ,已添加了映射类型,而在 [email 中添加了条件类型和类型推断。这一个变得非常简单:
type MappedReturnTypes<
T extends Record<string, (...args: any[]) => any>
> = { [K in keyof T]: ReturnType<T[K]> }
游乐场链接
