2017-01-12 9 views
2

エラーがわかりませんが、タイプスクリプトのエラーメッセージがあります。エラーメッセージは次のとおりです。エラーのあるプロミスを拒否したときのタイプスクリプトエラーTS2345

error TS2345: Argument of type '(error: Error) => void | Promise' is not assignable to parameter of type '(reason: any) => IdentityKeyPair | PromiseLike'. Type 'void | Promise' is not assignable to type 'IdentityKeyPair | PromiseLike'.

私のコードは正常に働いていたが、私はこのブロックを変更したときに活字体が私に怒っ:この中

.catch((error) => { 
    let identity: Proteus.keys.IdentityKeyPair = Proteus.keys.IdentityKeyPair.new(); 
    return this.store.save_identity(identity); 
}) 

:ここ

.catch((error) => { 
    if (error instanceof RecordNotFoundError) { 
    let identity: Proteus.keys.IdentityKeyPair = Proteus.keys.IdentityKeyPair.new(); 
    return this.store.save_identity(identity); 
    } else { 
    return reject(error); 
    } 
}) 

は完了です実行していたコード:

public init(): Promise<Array<Proteus.keys.PreKey>> { 
    return new Promise((resolve, reject) => { 
    this.store.load_identity() 
     .catch((error) => { 
     let identity: Proteus.keys.IdentityKeyPair = Proteus.keys.IdentityKeyPair.new(); 
     return this.store.save_identity(identity); 
     }) 
     .then((identity: Proteus.keys.IdentityKeyPair) => { 
     this.identity = identity; 
     return this.store.load_prekey(Proteus.keys.PreKey.MAX_PREKEY_ID); 
     }) 
     .then((lastResortPreKey: Proteus.keys.PreKey) => { 
     return resolve(lastResortPreKey); 
     }) 
     .catch(reject); 
    }); 
} 

そして、ここではをもうコンパイルされませんコードは次のとおりです。

public init(): Promise<Array<Proteus.keys.PreKey>> { 
    return new Promise((resolve, reject) => { 
    this.store.load_identity() 
     .catch((error) => { 
     if (error instanceof RecordNotFoundError) { 
      let identity: Proteus.keys.IdentityKeyPair = Proteus.keys.IdentityKeyPair.new(); 
      return this.store.save_identity(identity); 
     } else { 
      return reject(error); 
     } 
     }) 
     .then((identity: Proteus.keys.IdentityKeyPair) => { 
     this.identity = identity; 
     return this.store.load_prekey(Proteus.keys.PreKey.MAX_PREKEY_ID); 
     }) 
     .then((lastResortPreKey: Proteus.keys.PreKey) => { 
     return resolve(lastResortPreKey); 
     }) 
     .catch(reject); 
    }); 
} 

活字体コンパイラはエラーコードTS2345と私のreturn reject(error);文を拒否した理由は、誰もが見ていますか?

スクリーンショット:

error TS2345

私は活字体2.1.4を使用しています。

答えて

2

以下を試してください。あなたが当時またはキャッチブロックにいるときは、PromiseまたはPromiseにラップされた値を返すことができます。プロミスと一緒に手動で作業しているので、何も返さずに解決と拒否のハンドラを呼び出すことができます。 reject(error)を返すと、返された値をプロミスでラップし、次のthenブロックに渡そうとします。これは、あなたが行ったエラーを受けた理由です。このように考える:ハンドラで何かを返すことは、この新しい値でチェーンを続けることを意味します。あなたの場合は、連鎖をやめて、特定の条件の下であなたが作成しているPromiseを解決または却下したいと思うだけです。

public init(): Promise<Array<Proteus.keys.PreKey>> { 
    return new Promise((resolve, reject) => { 
    this.store.load_identity() 
     .catch((error) => { 
     if (error instanceof RecordNotFoundError) { 
      let identity: Proteus.keys.IdentityKeyPair = Proteus.keys.IdentityKeyPair.new(); 
      return this.store.save_identity(identity); 
     } else { 
      throw error; 
     } 
     }) 
     .then((identity: Proteus.keys.IdentityKeyPair) => { 
     this.identity = identity; 
     return this.store.load_prekey(Proteus.keys.PreKey.MAX_PREKEY_ID); 
     }) 
     .then((lastResortPreKey: Proteus.keys.PreKey) => { 
     resolve(lastResortPreKey); 
     }) 
     .catch((error) => { 
     reject(error); 
     }); 
    }); 
} 
+0

'return reject(error)'の代わりに 'reject(error)'を実行すれば、 'エラーTS7030:すべてのコードパスが値を返すわけではありません。 –

+0

私は同じことを達成する底のキャッチでちょうど捕らえられるエラーを投げるためにそれを変更しました。 – DeezCashews

+0

あなたが最後の '.then'ブロックで何もしていないので、私はKulvarがあなたに見せたように前のもので解決します。彼がしたように拒否を渡すか、手動でエラーをキャッチして自分で拒否するかは、あなた次第です。私は読むのが簡単だと思いますが、やや冗長です。 – DeezCashews

0

あなたのリターンは役に立たず、それはonRejectionコールバックの終了です。 そしてreturn reject()は、とにかく次の.then()の約束を果たします。 しかし、あなたがエラーを投げた場合、それは以下の約束に従って.catch(reject)に継承されます。

基本的に:任意のキャッチ/リターンでは、子の約束を解決し、スローは子の約束を拒否します。

私は、約束のチェーンのより良い流れのためにコードを書き直しました。

public init(): Promise<Array<Proteus.keys.PreKey>> { 
    return new Promise((resolve, reject) => { 
    this.store.load_identity() 
    .catch(
     (error) => { 
     if (error instanceof RecordNotFoundError) { 
      let identity: Proteus.keys.IdentityKeyPair = Proteus.keys.IdentityKeyPair.new(); 
      return this.store.save_identity(identity); 
     } else { 
      throw error; 
     } 
     } 
    ) 
    .then(
     (identity: Proteus.keys.IdentityKeyPair) => { 
     this.identity = identity; 
     resolve(this.store.load_prekey(Proteus.keys.PreKey.MAX_PREKEY_ID)); 
     }, 
     reject 
    ) 
    }); 
} 
+0

私のオリジナルのソースコードにはお返事ありがとうございます。私は長いdoSomething> catch>> then> catch> then> then resolveのような長いPromiseチェーンを持っています。だから、私が最初の 'catch'ブロックで' throw error'を実行すると、そのチェーンの2番目の 'catch'ブロックがトリガーされます。しかし私はそれを望んでいません。最初の 'catch'ブロックにエラーが見つかった場合、チェーン全体が壊れることを望みます。だから私は '返品拒否(エラー) 'のために行った。しかし、あなたの解決策では私はこのパターンに従うことができません。私の問題は約束を悪用することによってもたらされると思いますか?それとも、型マッピングが欠落していますか? –

+1

@BennyNeugebauer、あなたが求めるソリューションは、パターンベースであり、構文ベースではありません。 「Promiseのcatch/thenブロックから戻ってくる方法」の質問に[この回答](http://stackoverflow.com/a/32049994/3478010)を読む必要があります。 –

1

あなたがいなくても約束(あなたが他の約束のコンストラクタでの約束をラップすることになっていない)の明確な誤用であるreturnreject()、によって、プロミスチェーン(脇のキャンセル)を停止することはできません。

あなたができることから始めましょう。それからあなたがするべきことに行きましょう。

あなたはそれがあなたのタイプのガードと一致しない場合throwがそれをINGの再プロミスチェーンダウン拒否バブルを聞かせができ、すべての.catch()句が自分自身を使い果たした後、ラインの一番下に、プロミスはあなたから返されます機能が拒否されます。

を使用すると、同期コードでそれを行うだろうか考えてみてください。

try { 
    try { 
    actionThatThrows(); 
    } catch (err) { 
    breakEverything(); 
    } 
    continue other steps 
} catch(err) { 
    generalErrorHandling(); 
} 

この種のコードは問題ではなく、また約束でもOKではありません。別個のアクションを、独自に解決または拒否できる機能に移動し、意味のエラーを使用する必要があります。例外を処理することができるようになるまでスタックを泡立てる例外です。

また、TS 2.1.xを使用しているため、長い非同期フローの場合は、の非同期機能をお勧めします。

関連する問題