2017-03-28 22 views
3

クラス(MyClass)にオプションのパラメータを持つ関数(func)があります。オプションのパラメータ(MyInterface)の型は、オプションのプロパティのみを持ちます。typescriptオプションのパラメータ型チェック

数値のようなプリミティブでfooを呼び出すと、コンパイラエラーが予想されました。しかしそれはそうではありません。それはなぜそれのようなものですか?型システムにエラーとしてマークするように指示する方法はありますか?これが起こる

interface MyInterface { 
    foo?: string 
} 

class MyClass { 
    func(b?: MyInterface) : void {} 
} 

let c = new MyClass(); 
c.func(); 
c.func({ foo: 'bar' }); 
c.func({ foo: 30 });  // compiler error: OK 
c.func({}); 
c.func(60);    // No compiler error: Not what I expect 

答えて

2

理由は、number{}と互換性があることです。 (例えば、タイプ{toFixed: (n: number) => string}の引数は、numberと互換性があります)。

このように考えることもできます:数字で何でもできます。{foo?: string}で行うことができます。

+0

ダックタイピングのような音。 TypeScriptはダックタイピングの一種ですか?これとは対照的に、空のクラスも別の空のクラスとは異なるjavaもあります。 – stefku

+0

はい、オブジェクトは、そのインターフェイスに属するインターフェイスを実際に明示的に実装する必要はありません。プロパティは一致する必要があります。 'MyInterface'要件では、' 60'を 'MyClass.prototype.func'の中の数字として扱うことができません。 –

0

のは、いくつかの汚れにconsole.log-デバッグをご紹介しましょう:

interface MyInterface { 
    foo?: string 
} 

class MyClass { 
    func(b?: MyInterface): void { 
     console.log(`b:${b}`); 
     if (b != undefined) { 
      console.log(`b.foo:${b.foo}`); 
     } 
    } 
} 

let c = new MyClass(); 
c.func(); 
c.func({ foo: 'bar' }); 
c.func({ foo: 30 });  // compiler error: OK 
c.func({}); 
c.func(60);    // No compiler error: Not what I expect 

結果は以下のとおりです。

b:undefined 

b:[object Object] 
b.foo:bar 

b:[object Object] 
b.foo:30 

b:[object Object] 
b.foo:undefined 

b:60 
b.foo:undefined 

はのは、最後の二つの結果に焦点を当ててみましょう。

MyInterfaceは、さらにfooパラメータのみを持ち、さらにオプションです。だから、実際には何でもタイプはMyInterfaceです。そのため、パラメータbの値は60です。この場合、MyInterfacebは、オプションのfooメンバーなしです。

fooメンバーからオプションの演算子を削除すると、コンパイラは例外をスローします。 MyInterfaceに追加の非オプションパラメータを追加する場合も同様です。

多分直感的ではないようですが、そうではありません。あなたが提示した形式では、MyInterfaceは何も定義しません。入力を保護するようにコンパイラに指示して、fooのパラメータを持っているかどうかを確認してください。では、なぜ入力がobjectかどうかチェックする必要がありますか?

関連する問題