2017-06-04 110 views
2

如何爲一個函數編寫返回類型註釋,該函數接受一個對象,調用其所有方法並返回一個新對象,其中原始鍵映射到方法的返回值?用於調用對象方法的返回類型註釋

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

現在沒有辦法正確檢索方法調用的返回類型,因此我的解決方案只是部分。然而,在作品中有一個提案,你可以閱讀更多有關它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}); 
} 

由於所述方法的返回類型不能確定返回的對象的屬性的值類型將是任何。

如果返回類型是有限的,你可以將它們定義爲一個類型並使用它們(它並不完美,但可能會更好)。

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

雖然這不是完美的解決方案,我希望它可以幫助你。

注意:請原諒重寫的方法,使用看起來更清潔減少

相關問題