2017-06-04 5 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を読むことができます。

あなたが今できることは、少なくともあなたが今持っているものからもう少しタイピングすることです。

あなたができることの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}); 
} 

メソッドの戻り型は、返されたオブジェクトのプロパティの値型は、任意になるだろうと判断することができないので。

戻り値の型が有限であれば、それらを型として定義して使用することができます(完全ではありませんが、より良いかもしれません)。戻り値の型とオブジェクトのタイプの両方を使用すると、より汎用的な機能をするので、あなたは、あまりにも外部パラメータとしてそれらを渡すことができます知られているに渡されている場合は

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

これは、私はそれがあなたの役に立てば幸い完璧なソリューションではありませんが。

注:メソッドの書き換えをご容赦ください。を使用するときれいに見えましたを減らしてください。

関連する問題