2017-01-16 12 views
0

Iは、ラムダ関数はa引数に追加のプロパティを必要とするので、署名は互換性があってはならないので、このコードなぜこのlambda関数はtypescriptでエラーではありませんか?

let x: (a: { b: number }) => void = (a: { b: number, c: string }) => { alert(a.c) }; 
x({ b: 123 }); 

は、エラーが発生しなければならない想像。しかし、これを最新のタイスクリプトの遊び場で試しても、エラーは発生しません!何故ですか?

+0

は厳密に実際の機能は限り構造的なタイピングが懸念しているとして、xの型と一致しない話します。 – toskv

答えて

0

あなたが言ったとき

let x: (a: { b: number }) => void

あなたが言っている「xはbキーを持つオブジェクトをとる関数です。」

次に、bキーとcキーを持つオブジェクトを取得したラムダを割り当てました。渡されるオブジェクトにはbキーが必要なので、型チェッカーに渡されます。

次に、bキーを持つオブジェクトを渡します。エラーはありません。

あなたはそれが理由cキーで失敗する場合、xのタイプは、次の行います

let x: (a: { b: number, c: string }) => void

+0

申し訳ありませんが、私はまだ*なぜ*これはエラーではないでしょう。 cキーを必要とするラムダは、bキーだけのオブジェクトを渡すことができませんでした。それで、どのようにそれを受け入れるxの型に割り当てることができますか?私の考えは、引数の型がラムダが想定できる一連の保証であるということです。それをxに割り当てることはそれを破るので、許可しないでください。 – Ludwik

+0

これは、あまり正確でない型の変数に、より正確なラムダを与えているからです。 'let x:Animal = new Cat()'と言ったとしましょう。 「動物」は「猫」のすべての特性を持っていないかもしれませんが、それは明らかにうまくいくでしょう。より多くのプロパティを必要とするラムダを、型が必要な変数に割り当てることは、エラーでもありません。 – thedayturns

+0

確かに、それはオブジェクトには完全に意味がありますが、それは関数の逆の方法ではありませんか?オブジェクトでは、 'let x:Cat = new Animal()'を実行することはできませんが、反対に行うことができます。なぜなら、Catの詳細に関わらず、Animalが行うことができるすべてを行うことができるからです。関数では、動物をパラメータとする関数fは猫をとりますが、特に猫をとる関数gは動物をとることができませんでした。言い換えれば、 'f'はすべての入力' g'を処理できますが、他の方法では*できません。したがって、 'f = g'は受け入れられるべきですが、' g = f'ではないようです。 – Ludwik

関連する問題