2017-11-14 16 views
0

次の例では、TypeScriptコンパイラはからに直接キャストできません。実際には、コメント付きの行に示されているように、中間変数tempまたはdouble castingを使用することは可能です。 バグですか?それとも論理的な説明がありますか? playgroundTypescript: "this"のダウンキャストはできません

class Parent { 
     prop: string = null; 
     castToChild(): Child{ 
      let temp: Parent = this; 
      return this as Child; 
      //return temp as Child; 
      //return this as Parent as Child; 
     } 
    } 
    class Child extends Parent 
    { 
     otherProp: string = null; 
    } 

答えて

0

へのリンクあなたは直接コンパイラがParentインスタンスが本当にChildであることを知る方法がないという理由だけでChildParentをキャストすることはできません。代わりに、キャストの型ガードを使用してください:警備ifコンパイラ内部

class Parent { 
    prop: string|null = null; 
    isChild(): this is Child { 
     return (this as any).otherProp !== undefined; 
    } 
} 
class Child extends Parent 
{ 
    otherProp: string|null = null; 
} 

function test(p: Parent) { 
    if (p.isChild()) { 
    console.log(p.otherProp); 
    } 
} 

は今それpはまだちょうどParentある外pは、Childであることを知っています。

またはより良いまだ、サブクラスでガードをオーバーライドして、あなたはまったく型キャストを行うことを避けることができます。

class Parent { 
    prop: string|null = null; 
    isChild(): this is Child { 
     return false; 
    } 
} 
class Child extends Parent 
{ 
    otherProp: string|null = null; 
    isChild(): this is Child { return true; } 
} 

function test(p: Parent) { 
    if (p.isChild()) { 
    console.log(p.otherProp); 
    } 
} 

あなたが、私はこれはバグか意図的であるかどうかを疑問に答えていないことが適切ですTypescriptの著者の側では、私の推測では、可能性のあるエラーをキャッチしようとしているのですが、確認または拒否するこの正確な動作の説明を見つけることはできませんでした。あなたがあなたの元のコードの作業を行うことができます

もう一つの方法は、明示的castToChild方法でthisの種類を活字体伝えることです:

class Parent { 
    prop: string|null = null; 

    castToChild(this: Parent): Child{ 
     return this as Child; 
    } 
} 
class Child extends Parent 
{ 
    otherProp: string|null = null; 
} 

function foo() { 
    let p: Parent = new Child(); 
    let c = p.castToChild(); 
    console.log(c.otherProp); 
} 

これはまだ実際にはダブルキャストをやっているが、おそらく少しクリーナーを探します。しかし、明示的なthisパラメータthisはタイプParentですが、キャスト可能な明示的なパラメータを使用して直接キャストできないため、動作の不思議さが表示されます。

+0

申し訳ありませんが、私はあなたの解決策があまりにも複雑であると感じています。中間変数を持つ、またはダブルキャストを使用することで私の回避策ははるかに短く、追加のコードを必要としません。しかし、それらは不要な構文的ノイズを生成します。私はコンパイラが親が実際に子どもであることを知らないことに同意しますが、これが正確に私がキャスティングを行う理由です。 –

+0

面白い意見。確かにtypescriptを使うのは、あなたが間違っているとコンパイラがあなたに知らせることができないことがあるからです。あなたはいつもjavascriptを使わず、これらの型について全く心配する必要がないので、コンパイラよりもよく分かっているのですか? – Duncan

+0

私の答えが何とかあなたを怒らせてしまったのであれば申し訳ありませんが、確かに私の意図ではありませんでした。しかし、あなたの提案は私の質問ではまだ答えではありません: "TS-コンパイラがキャストを二重キャストとして受け入れるか中間変数を使うのはなぜですか? 1つではなく2つのステップを使用して同じ方法を実行することは、私が「構文的ノイズ」と呼んだものです。 –

関連する問題