TypeScriptは、スケーラブルなJavaScriptアプリケーションを構築するための強力なツールであり、大規模なWeb JavaScriptプロジェクトの標準となっています。ただし、初心者の場合、TypeScriptにはいくつかのトリッキーなものもあり、その1つは組合タイプを区別しています。
次のコードを検討してください。
インターフェイスキャット{ 重量:番号; ひげ:番号; } インターフェイスドッグ{ 重量:番号; フレンドリー:boolean; } 動物を飼ってください:犬。
多くの開発者は、 animal
にアクセスするときにweight
属性のみが有効である一方で、 whiskers
やfriendly
属性が無効であることに驚くでしょう。この記事では、その理由を説明します。
それに飛び込む前に、組合タイプ間のタイプスクリプトの区別を理解するのに役立つ構造的および名目上のタイプをすばやく確認しましょう。
構造タイプを理解する最良の方法は、それらを公称タイプと比較することです。使用した可能性のある入力言語のほとんどは、名目上タイプされています。たとえば、C#コード(JavaまたはC同様):
クラスfoo { public int x; } クラスブラ{ public int x; }
Foo
とBlah
まったく同じ構造を持っていても、彼らは互いに値を割り当てることができません。次のコード:
blah b = new foo();
次のエラーが生成されます。
<code>无法隐式转换类型“Foo”为“Blah”</code>
これらのクラスの構造は重要ではありません。タイプFoo
の変数は、 Foo
クラス(またはそのサブクラス)のインスタンスにのみ割り当てることができます。
それどころか、タイプスクリプトは構造タイプを採用します。 TypeScriptは、両方のタイプが同じ構造を持っている場合、それらを互換性のあるものと見なします。
したがって、次のコードは正常に機能します。
クラスfoo { X:number = 0; } クラスブラ{ X:number = 0; } F:foo = new blah(); b:blah = new foo();
これをさらに説明しましょう。次のコードが与えられます:
クラスfoo { X:number = 0; } f:foo;
f
、 Foo
クラスインスタンスと同じ構造であるすべてのオブジェクトを保持できる変数です。この場合、数字を表すx
プロパティを意味します。これは、通常のJavaScriptオブジェクトでさえ受け入れることができることを意味します。
f:foo; f = { X:0 };
この記事の冒頭でコードに戻りましょう。
インターフェイスキャット{ 重量:番号; ひげ:番号; } インターフェイスドッグ{ 重量:番号; フレンドリー:boolean; }
私たちは知っています:
動物をさせてください:犬;
Dog
インターフェイスと同じ構造のオブジェクトをanimal
にします。では、次のコードとはどういう意味ですか?
動物を飼ってください:犬。
これにより、 animal
種類がDog
インターフェイスに一致するオブジェクト、またはCat
インターフェイスに一致するオブジェクトとして定義します。
では、なぜanimal
weight
属性にのみアクセスできるようになったのですか?簡単に言えば、それはタイプスクリプトがそれがどんなタイプであるかを知らないからです。タイプスクリプトはanimal
Dog
またはCat
でなければならないことを知っていますが、どちらかかもしれません。 friendly
財産にアクセスすることを許可されているが、インスタンスではanimal
実際にはCat
ではなくDog
ではない場合、ランタイムエラーが発生する可能性があります。 whiskers
属性にも同じことが言えます。
ユニオンタイプは、属性の組合ではなく、有効な値の組合です。開発者はしばしばこのようなコードを書きます:
動物を飼ってください:犬。
そして、 animal
Dog
とCat
特性の結合を持っていることを期待してください。しかし、これは別の間違いです。これはanimal
有効なDog
と有効なCat
価値の関節に一致する値があることを指定しています。ただし、TypeScriptでは、存在することがわかっているプロパティにのみアクセスできます。現在、これは組合内のあらゆる種類のプロパティを意味します。
今、私たちは持っています:
動物を飼ってください:犬。
animal
がDog
であるとき、 Dog
インターフェイスのDog
としてそれを正しく扱い、アクセス特性をどのように扱い、 Cat
のときにそれを処理しますか?現在、 in
Operatorを使用できます。これは古いJavaScriptオペレーターであり、あまり頻繁に表示されない可能性があります。これにより、プロパティがオブジェクトに存在するかどうかをテストできます。例えば:
o = {a:12}とします。 「a」in // true oの「x」; // false
TypeScriptはin
オペレーターと深く統合されていることがわかります。使用方法を見てみましょう:
動物:犬|。 if(動物の「フレンドリー」){ console.log(animal.friendly); } それ以外 { console.log(animal.whiskers); }
このコードはエラーを生成しません。 if
ブロック内で、TypeScriptはfriendly
財産があることを知っているので、 animal
Dog
に変換します。 else
ブロック内で、タイプスクリプトも同様にanimal
をCat
として扱います。これらのブロック内のanimal
オブジェクトの上にマウスをホバリングすることで、これをコードエディターで表示することもできます。
ここでブログ投稿が終了することを期待するかもしれませんが、残念ながら、属性が存在するかどうかを確認することにより、組合タイプを狭めることが非常に制限されます。シンプルなDog
とCat
種類に適していますが、これらのタイプの間でより多くのタイプとより重複している場合、物事はより複雑で壊れやすくなります。
これは、ユニオンタイプを区別するのに役立つ場所です。私たちはすべてを以前から保持し、各タイプにプロパティを追加するだけです。その唯一の目的は、これらのタイプを区別(または「区別」する)ことです。
インターフェイスキャット{ 重量:番号; ひげ:番号; Animal_type: "cat"; } インターフェイスドッグ{ 重量:番号; フレンドリー:boolean; Animal_type: "dog"; }
両方のタイプのANIMAL_TYPE
属性に注意してください。 2つの異なる値の文字列と間違えないでください。 ANIMAL_TYPE: "CAT";
たまたま「猫」を含むタイプを表します。
今、私たちの検査はより信頼性が高まっています:
動物:犬|。 if(animal.animal_type === "dog"){ console.log(animal.friendly); } それ以外 { console.log(animal.whiskers); }
このチェックは、組合に参加する各タイプがANIMAL_TYPE
属性の異なる値を持っていると仮定して、絶対確実になります。
唯一の欠点は、新しいプロパティに対処する必要があることです。 Dog
またはCat
のインスタンスが作成されるたびに、 ANIMAL_TYPE
のユニークな正しい値を提供する必要があります。しかし、タイプスクリプトがあなたに思い出させるので、忘れることを心配しないでください。 ?
詳細を確認したい場合は、Typeの狭窄に関するTypeScriptドキュメントをお読みください。これにより、ここで議論していることをより詳細に調べます。このリンクには、タイプアサーションに関するセクションがあります。これらを使用すると、タイプの判別器を使用したり、 in
キーワードに依存したりせずに、独自のカスタムチェックを定義してタイプを狭くすることができます。
この記事の冒頭で、次の例では、なぜweight
が唯一のアクセス可能な特性であるのかと言いました。
インターフェイスキャット{ 重量:番号; ひげ:番号; } インターフェイスドッグ{ 重量:番号; フレンドリー:boolean; } 動物を飼ってください:犬。
私たちが学んだことは、TypeScriptはanimal
Dog
やCat
になることができることしか知っていないが、両方ではないことを知っているということです。したがって、私たちはweight
を得ることができます。これは2つの間の唯一の公共財産です。
組合タイプを区別するという概念は、TypeScriptがこれらのオブジェクトを区別する方法であり、このアプローチは、より大きなオブジェクトのコレクションであっても非常にスケーラブルです。したがって、チェックに使用できる単一のリテラル値を保持する両方のタイプに新しいANIMAL_TYPE
プロパティを作成する必要があります。もちろん、これは追跡する必要があるもう1つのことですが、より信頼性の高い結果も生成します。これは、そもそもTypeScriptに必要なものです。
以上がタイプスクリプトを区別した組合を分類しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。