TypeScriptでは、このようにPromiseのタイプを定義できるようにしたいので、次のようにします。
_//This works today:
new Promise<number>((resolve)=>{
//Cool
resolve(5);
//Error, because I didn't pass a number:
resolve();
}
//This is what I want to do also:
new Promise<void>((resolve)=>{
//Error, because I passed a value:
resolve(5);
//Cool, because I declared the promise to be of type void, so resolve doesn't take a value:
resolve();
}
_
私が見たすべてのpromise定義ファイルは、promiseの「解決」メソッドが値を取る必要があることを宣言しています。 ここ は、すばらしいDefinitelyTypedプロジェクトの最近の例です。
_declare class Promise<R> implements Thenable<R> {
constructor(callback: (resolve : (result: R) => void, reject: (error: any) => void) => void);
///...
}
_
「」
つまり、「解決コールバックにはタイプRの値を渡す必要があります。」 _new Promise<number>
_のようなpromiseはそれで問題ありません。 TypeScriptは、タイプnumber
の値でresolveを呼び出していることを確認します。
ただし、値がないプロミスが必要な場合、値を渡さずにresolve()を呼び出せるようにしたい場合はどうすればよいですか?私は次のように自分の約束を宣言できます:_new Promise<void>
_しかし、それでもresolveを呼び出して、ある種の値を渡す必要があります。私はresolve(undefined)
を呼び出すことができますが、少し奇妙に読みます。
TypeScriptでこの概念を正しくキャプチャする方法はないようです。「このジェネリックの型が 'void'の場合、この関数のパラメーターを期待しないでください。」
私ができる最も近いことは、resolveメソッドで結果をオプションとしてマークすることですが、これは、型付きバージョンの場合でも、結果がalwaysオプションであることを意味します約束。
私mightが満足のいく回避策を考え出したところです。 _Promise<void>
_を使用したい場合、resolve
コールバックはnotではなく、パラメーターを受け取ります。 resolveメソッドが常にオプションのパラメーターを取るようにすると、次のように新しいクラスを定義できます。
_export class VoidPromise extends RSVP.Promise<void>{
//Note that resolve does not take a parameter here:
constructor(callback:(resolve:() => void, reject:(error:any) => void) => void){
super(callback);
}
}
_
その場合、次のように使用できます。
_ public static testVoidPromise() : VoidPromise{
return new VoidPromise((resolve, reject)=>{
setTimeout(1000, ()=>{
if (Math.random() < 0.5){
//Note that resolve() does NOT take a parameter
resolve();
}else{
reject(new Error("Something went wrong"));
}
})
});
}
_
確かに、開発者は単に「Promise」の代わりにVoidPromiseを使用する必要がありますが、意図した効果は、resolveパラメーターをオプションとして誤ってマークする必要なく達成されます。
私のシナリオでは、上記のコードはallresolve
メソッドをオプションの結果としてマークするよりも私の期待に応えています。マークallは、99%の場合、オプションで危険と感じます。常にオプションである場合は、_Promise<number>
_を宣言し、結果なしでresolve()
を呼び出し、約束に従ってundefined
結果を取得できます。その場合、私はその約束を拒否するべきでした。 resolveメソッドのパラメーターが本当にオプションであるとは期待されていません。 (ソース: https://github.com/domenic/promises-unwrapping#the-promise-constructor )
Promiseインターフェースを使用する方法から、値を渡したい場合もあれば、値を渡さないようにしたい場合もあるので、それがオプションのパラメーターの目的です。 「未定義」の結果でプロミスを解決することが受け入れられない場合(IMOこれは悪い考えではありません。これは、コードで何が起こっているかを正確に伝えます-プロミスの結果is udefined)解決策を提案できますそれはあなたが探しているもののようです:
私は約束の「契約」を定義しますと言いましょう:
export interface IMyPromiseResult {
result: number;
}
そしてそれを約束とともに使用する:
new Promise<IMyPromiseResult>((resolve)=>{
resolve(<IMyPromiseResult>{ result: 5 });
resolve(<IMyPromiseResult>{ });
}
このアプローチはもう少し複雑ですが、いくつかの興味深いオプションが開かれます...一方、現在のDefinitelyTyped Promiseコンストラクターは次のように定義されます。
constructor(callback: (resolve: (result?: R) => void, reject: (error: any) => void) => void);
したがって、オプションの結果を持つことは許可されており、それで問題ありません。