返回类型注释,用于调用对象的方法

时间:2017-06-04 22:39:04

标签: typescript typescript2.3

如何为接受对象的函数编写返回类型注释,调用其所有方法,并返回一个新对象,其中原始键映射到方法'返回值?

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

2 个答案:

答案 0 :(得分:3)

现在无法正确检索方法调用的返回类型,因此我的解决方案只是部分解决方案。但是,有一项提案正在进行中,您可以阅读更多相关信息here

你能做的最好的事情就是至少从现有的东西中打字。

您可以做的一件事是使用映射类型来从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 似乎更清晰。

答案 1 :(得分:0)

typescript@2.1 开始,已添加 mapped typestypescript@2.8 conditional types 和类型推断。这个真的很容易:

type MappedReturnTypes<
    T extends Record<string, (...args: any[]) => any>
> = { [K in keyof T]: ReturnType<T[K]> }

playground link