2016-11-01 7 views
1

ユニオンタイプのユーザー定義型ガードが対称的に動作しないという問題が発生しました。私はこれが私の最終的なエラーです: -/Typescriptコンパイラでこれがエラーですか?

test2()に問題が現れ、タイプガードからタイプが正しく推測されません。

class PropPacket { 
    constructor(public key: string, public value: number) {} 
} 

class EventPacket { 
    constructor(public key: string) {} 
} 

type Packet = PropPacket | EventPacket; 

function isPropPacket(p: EventPacket | PropPacket): p is PropPacket { 
    return p instanceof PropPacket; 
} 

function isEventPacket(p: EventPacket | PropPacket): p is EventPacket { 
    return p instanceof EventPacket; 
} 

function test1(p: Packet) { 
    if (isPropPacket(p)) { 
     // `p` is PropPacket 
     p.key; 
     p.value; 
    } else { 
     // `p` is EventPacket 
     p.key; 
    } 
} 

function test2(p: Packet) { 
    if (isEventPacket(p)) { 
     p.key; 
    } else { 
     // ERROR: thinks `p` is `never` type 
     p.key; 
     p.value; 
    } 
} 

すべてEventPacket sが実際にPropertyPacket秒ですので、これが起こる(https://www.typescriptlang.org/play/

+0

興味深い。私は言語弁護士ではありませんが、価値のあるものについては、 'Packet'型の' key'プロパティの名前を何か他のものに変更すると期待しているように振る舞います。 'key2'。 – cynic

答えて

1

typescriptです遊び場にコードを貼り付けることで、問題を見ることができます。 Typescriptは、2つのクラスが宣言によって区別されるとは考えていない構造型システムを持っています。

+0

あなたが正しいと思われます。未使用のプライベートプロパティをEventPacket宣言に追加すると、問題が解決されます。システムの醜い副作用だと思います。 – bjnsn

+0

私はそれが必ずしも悪いことではないと言います。一方では、実行時の動作(悪い)と一致しません。他方では、この種のコードを駄目にします(良い)。 –

関連する問題