私は次の機能を持っています:
function demo<T>(init: T) {
return init;
}
省略した場合init
のデフォルト値を指定したいと思います{}
。だから私は書いた:
function demo2<T>(init: T = {}) {
return init;
}
しかしもちろん、これは私にエラーを与えます:
Type '{}' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to '{}'.(2322)
どのように私は強制できT
ように{}
パラメータが省略されたとき?ありがとうございました。
エラーは技術的に正しいです。関数の呼び出し元はdemo2()
、typeパラメーターT
を希望どおりに指定できます。つまり、次のような呼び出しではコンパイラエラーは発生しませんが、ランタイムエラーが発生しやすくなります。
const z2 = demo2<{ a: number }>(); // uh oh, no error
z2.a.toFixed(); // no error at compile time but "z2.a is undefined" at runtime
あなたが(手動でジェネリック型パラメータを指定する)ことをやって誰かの可能性は低いと思われる場合それでも、あなたは使用することができるタイプのアサーションを同時に使用している間、エラーを抑制するために、一般的なパラメータのデフォルトコンパイラが推測されるように{}
するためにプロパティT
を除外する場合init
:
// assertion with default type parameter
function demo3<T = {}>(init: T = {} as T) {
return init;
}
これにより、次の望ましい動作が得られます。
const x3 = demo3(); // {}
const y3 = demo3({ a: 123 }); // {a: number}
それでも次の望ましくない動作を許可します。
const z3 = demo3<{ a: number }>(); // no compiler error
z3.a.toFixed(); // RUNTIME ERROR!
T
タイプの値を渡さずに手動で指定することを禁止したい場合は、複数の呼び出しシグネチャを持つオーバーロードされた関数のT
ようなものを使用することを検討してください。
//オーバーロード
function demo4(): {};
function demo4<T>(init: T): T;
function demo4(init = {}) {
return init;
}
ここで、呼び出し元がinit
パラメーターを省略した場合、関数は汎用として扱われなくなります。戻り値の型はちょうど{}
です。一方、呼び出し元がinit
パラメーターを指定した場合、関数は元のdemo()
関数と同じように扱われます。関数の実装は、どちらの呼び出しシグネチャでも機能します。
これにより、「通常の」呼び出しの望ましい動作も得られます。
const x4 = demo4(); // {}
const y4 = demo4({ a: 123 }); // {a: number}
また、誰かがそれを間違った方法で呼び出そうとすると、コンパイラに警告を出します。
const z4 = demo4<{ a: number }>(); // compiler error! an argument for init is required
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加