2017-02-23 7 views
1

私は、プロンプトを増やそうとしています。それには、TypeScriptドキュメントのGlobal augmentationで説明されているように余分なメソッドを追加します。プロミスの拡張は、新しいプロミス(...)のタイプ推論を中断する

そして、それはテスト1で正常に機能しますが、何らかの理由で、それは約束のための型推論を破るには、テストでコンストラクタを使用して作成2.活字体はPromise<boolean>として推論タイプを停止し、代わりにPromise<{}>としてそれを推測します。私の拡張を取り除くと、コンストラクターを使って作成されたPromiseのジェネリック型が正しく推論されます。

なぜ起こるのか、どのように修正するのですか?ここで

は、私が何をしようとしているの簡単な例です:

// src/test.ts 

// augmentation 
interface Promise<T> { 
    myCustomMethod(): T; 
} 

// test 1 
let data: number = Promise.resolve(42) 
    .then((value) => value + 4) 
    .myCustomMethod(); 

// test 2 
let p2: Promise<boolean> = new Promise((resolve) => { 
    resolve(true); 
}) 

そして、私の設定:私は取得しています

// tsconfig.json 
{ 
    "compilerOptions": { 
     "module": "es6", 
     "target": "es6", 
     "baseUrl": "./src" 
    } 
} 

エラーは次のとおりです。

src/test.ts(9,5): error TS2322: Type 'Promise<{}>' is not assignable to type 'Promise<boolean>'. 
    Type '{}' is not assignable to type 'boolean'. 

UPD

私はそのタイプが常にテスト2のためにPromise<{}>と推測されているのを見ています。しかし、今私は理解できません、なぜこのエラーは私の増強なしでは報告されません。 Type '{}' is not assignable to type 'boolean'.以降、このエラーは増強なしで表示されるべきではありませんか?

それが意図されているかどうかを理解しようとしているか、TypeScript開発者に報告してください。

答えて

1

活字体を使用することによってこの問題を回避することができますが、必ず約束< {}も、あなたの増強せずに、この構築物について>タイプを推測:

new Promise((resolve, reject) => { 
    resolve(true); 
}) 

エラーによって証明されるように、この割り当てのメッセージ:

let z: void = new Promise((resolve, reject) => { 
    resolve(true); 
}) 

タイプ「約束<は、{}>」あなたはPromisemyCustomMethod(): T;を追加するとき

だから、副作用として、それはPromise<boolean>との互換性Promise<{}>ます「無効」型に代入できません。

(あなたは未解決の約束をmyCustomMethod()を呼び出すときに、どこそれは返す必要がありますT値を得るのだろうか?)ということを行う、またはあなたの約束構築するときに、明示的、一般的な引数を使用していない次のいずれかのために

let p2: Promise<boolean> = new Promise<boolean>((resolve) => { 
    resolve(true); 
}) 
+0

感謝をあなたは答えて回避策を講じます。更新された質問をご覧ください。私の増強なしにエラーがなぜ現れないのかを詳しく説明できますか? –

+1

あなたの増強なしでは、 'T'は関数の引数型として' Promise'にのみ表示され、TypeScriptには[関数互換性規則]があります(https://www.typescriptlang.org/docs/handbook/type-compatibility.html# 'boolean'は' {} 'に代入できるので 'function(x:{})'を 'function(x:boolean)'とコンパチブルにしています。戻り値に 'T'を付けると、' {} 'が' boolean'に代入されないので、それらは互換性がありません。 – artem

+1

[関数型の互換性を示す例](https://www.typescriptlang.org/play/#src=var%20f1%20%3D%20function%20(x%3A%20ブール値)%3A%20無効【請求項2】請求項1に記載の方法であって、前記第1の電極は、前記第1の電極と前記第2の電極との間に配置され、 0D%0Af1%20%3D%20F2%3B%20%2F%2F%20ok%0D%0Af2%20%3D%20F1%3B%20%2F%2F%20ok%0D%0A%0D%0Avar%20f3% 20%3D 20%20%20%20%20%20%20%10%20%7%20%10%20%7% 20%7B%20%20%7%7%7%3%20%3%20%3%20%3%20%3%20%3%20%3%20%3%20%3% 20%2F%2F%20ok%0D%0A) – artem

2

コンパイラは、Promise.resolve(42)という定数でPromise.resolve()を呼び出すという単純なケースで、引数からジェネリックの型を推論できます。 resolve(true)への呼び出しで型が明白になったような、より複雑な状況では失敗する可能性があります。

これはTypeScript Handbookで文書化されています

型引数の推論が短く、より読みやすいコードを維持するために有用なツールになることができますが、あなたは我々が以前に行ったように、明示的に型引数に渡す必要があるかもしれませんより複雑な例のようにコンパイラが型を推測しない場合の例です。

あなたは

let p2: Promise<boolean> = new Promise<boolean>(resolve => { 
    resolve(true); 
}); 
関連する問題