2017-01-31 7 views
1

Typescriptが提供する型保証の程度を理解しようとしています。私はエラーが予想されるシナリオを見つけましたが、Typescriptは不平を言っていません。Typescript関数が無効な引数をエラーなしで受け入れる

特定のインターフェイスに一致するパラメータを持つ関数を定義しました。次に、一致しない引数を使って関数を呼び出します。ここでは、コードは(or in playground)です:私の引数の変数が明示的に互換性のないインターフェースを宣言した場合、予想通り

interface ArgumentInterface { 
    [key: number]: string 
} 

interface InvalidArgumentInterface { 
    [key: string]: number 
} 

interface InvalidArgumentInterface2 { 
    foo: number 
} 

function myFunction(arg: ArgumentInterface) { 
    // function body 
} 

let validArgument: ArgumentInterface = {}; 
validArgument[5] = 'I am a string'; 

let invalidArgument: InvalidArgumentInterface = { 
    foo: 42 
}; 

let invalidArgument2: {foo: number} = { 
    foo: 42 
}; 

let invalidArgument3: InvalidArgumentInterface2 = { 
    foo: 42 
}; 

let invalidArgument4 = { 
    foo: 42 
}; 

myFunction(validArgument); // no typescript error, as expected 
myFunction(invalidArgument); // typescript error, as expected 
myFunction(invalidArgument2); // no typescript error! 
myFunction(invalidArgument3); // typescript error, as expected 
myFunction(invalidArgument4); // no typescript error! 

、私は活字体エラーを取得します。しかし、私の引数変数が(インターフェイスなしで)型リテラルを宣言するか、まったく型を宣言しない場合、Typescriptはエラーを予期しますが、まったく文句を言うことはありません。

"noImplicitAny"フラグをtrueに設定しました。

誰でもこの現象を説明できますか?

答えて

2

ここ

let a = { 
    1: "one", 
    2: "two", 
    foo: 4 
} 

数字で索引付けされるものは文字列値を持ちますが、foo索引には数値があります。

ArgumentInterface場合は、次のとおりです。

interface ArgumentInterface { 
    [key: number]: string; 
    [key: string]: string; 
} 

次に、あなたは、あなたがそれらを期待エラーが発生します。

+0

私が誤解したことを発見したと思います。[key:number]のインデックスシグネチャを定義しても文字列キーの追加が妨げられることはありません。あれは正しいですか? – Brian

+0

はい、そうです。しかし、それは別の方法では動作しません。また、jsオブジェクトのキーは**常に**文字列であることに注意してください。数字を渡すと文字列に変換されます。あなたが本当に数字と文字列の間にマップを望むなら、 'Map' –

1

TypeScript uses structural typing(Ocamlのような)です。

invalidArgument2およびinvalidArgument4は、いずれも構造的にArgumentInterfaceと互換性があり、したがって、タイプスクリプトはそれらをうまく受け入れます。その種類は{ foo: number; }であり、それはArgumentInterfaceの定義と矛盾しない、値は両方の可能性があるので

myFunction(invalidArgument2); 
myFunction(invalidArgument4); 

:あなたはのためのエラーを取得していない

+0

いいえ、これらは同等ではありません。 'ArgumentInterface'は' {[k:number]:string} '型であり、他の2つは' {foo:number} '型です。それらは異なる構造です。 –

+0

は "compatible"という言葉に置き換えられました。これは私がリンクしているドキュメントで使用されています。 – Ven

+0

さて、互換性はより理にかなっています。しかし、私は両者の間に矛盾がないと言いたい。 –

関連する問題