2017-11-30 9 views
2

はい、この質問のひどいタイトルについては申し訳ありませんが、説明するのは難しいです。いくつかのコードを表示し、に私が意図した通りに動作しない理由をもっと簡単に教えてください。TypeScriptの別の汎用パラメータに基づくジェネリック型パラメータの推定

interface Doer<U> { 
    doStuff:() => U; 
} 

class Promiser implements Doer<Promise<string>> { 
    doStuff() { 
     return Promise.resolve('foo'); 
    } 
} 

export interface Type<T> extends Function { 
    new (...args: any[]): T; 
} 

function doYourThing<T extends Doer<U>, U>(doer: Type<T>): U { 
    return new doer().doStuff(); 
} 

const result = doYourThing(Promiser); 
// type of "result" is `{}` 
// I want it to be `Promise<string>` 

上記コードcan be found hereの編集可能バージョン。

私はこれが可能である場合にもわからないんだけど、私は活字体は、引数の型Doer<U>のものであり、実際の引数が型であるという事実に基づいてdoYourThing()の戻り値の型を推論できるようにしたいと思いDoer<Promise<string>>

私は可能なことを試みていますか(私は現在TypeScript 2.4.2を使っています)?

もしそうなら、私はここで間違っていますか?

答えて

3

このような高級タイプの統一は、残念ながらボックスの中では機能しません。 "軽量高級タイピング"(TypeScriptの例here)に概説されているHKTのやや面倒な "平坦化"エンコーディングがあり、そこからより良い推論を得ることができます。

は幸いにもあなたの例のために、物事を再配置する簡単な方法があります:

... 

function doYourThing<T>(doer: Type<Doer<T>>): T { 
    return new doer().doStuff(); 
} 

const result = doYourThing(Promiser); 
// result is `Promise<string>` 
関連する問題