TypeScript における型保護の詳細な説明

TypeScript における型保護の詳細な説明

概要

TypeScript で共用体型を使用するとき、次のような厄介な状況に遭遇することがよくあります。

インターフェース バード {
  	// 固有メソッド fly();
  	// パブリックメソッド layEggs();
}

インターフェース Fish {
  	// 固有メソッド swim();
  	// パブリックメソッド layEggs();
}

関数 getSmallPet(): 魚 | 鳥 {
    // ...
}

ペットを getSmallPet() にします。
pet.layEggs(); // 正常 pet.swim(); // ts エラー

上記のように、getSmallPet 関数は Fish 型と Bird 型の両方のオブジェクトを返すことができます。返されるオブジェクトの型は不確定であるため、ユニオン型オブジェクトで共有されるメソッドを使用する場合はすべて正常に動作しますが、各ユニオン型オブジェクトに固有のメソッドを使用すると ts はエラーを報告します。

では、この問題をどう解決すればよいのでしょうか?最も残酷な方法は、もちろん、ユニオン型を any に変換することですが、結局のところ、AnyScript ではなく TypeScript を記述しているのだから、この方法は推奨する価値がありません。

この時点で、私たちは今日の主役型プロテクションを使用します。これは輝かしいデビューを果たし、この問題を完璧に解決できます。

孔易記はかつて、フェンネル豆の書き方には 4 つの方法があると言いました。同様に、型保護の書き方にも 4 つの方法があります。

型アサーション

型アサーションは、型を直接指定する最も一般的に使用される型保護方法です。 TypeScript で認識される型のほとんどは TypeScript の自動型推論によって計算されるため、上記のような問題が発生します。つまり、TypeScript は特定のオブジェクト型が何であるかを知らないため、各ユニオン型に固有のメソッドがあるかどうかはわかりません。

型アサーションを使用して型を直接指定すると、TypeScript の God モードをオンにするのと同じになり、特定の型がユニオン型内の型であることを直接知ることができます。このとき、オブジェクトの unique メソッドを使用することは、TypeScript の推論と一致しています。

インターフェース バード {
  // 固有メソッド fly();
  // パブリックメソッド layEggs();
}

インターフェース Fish {
  // 固有メソッド swim();
  // パブリックメソッド layEggs();
}

関数 getSmallPet(): 魚 | 鳥 {
  // ...
}

ペットを getSmallPet() にします。
pet.layEggs(); // 通常 // アヒルの種類で判断 if ((pet as Bird).fly) {
  // 型アサーション (pet as Bird).fly()
} それ以外 {
  // 型アサーション (pet as Fish).swim()
}

型アサーションが十分に洗練されていないと思われる場合は、ジェネリック型の記述方法を使用することもできます。

ペットを getSmallPet() にします。
pet.layEggs(); // 通常 // アヒルの種類で判断 if ((<Bird>pet).fly) {
  (<Bird>pet).fly()
} それ以外 {
  (<魚>ペット).swim()
}

ヒント: 型アサーションにジェネリック型の記述を使用する方が高度に思えますが、tsx の文法上の曖昧さのため、統一性を保つために、型アサーションには as メソッドを使用することをお勧めします。

構文では

js では、指定されたプロパティが指定されたオブジェクト内またはそのプロトタイプ チェーン内にあるかどうかを判断するために、 in 構文がよく使用されます。

同様に、TypeScript でも、次のようにしてオブジェクトの型を確認できます。

インターフェース バード {
  // 固有メソッド fly();
  // パブリックメソッド layEggs();
}

インターフェース Fish {
  // 固有メソッド swim();
  // パブリックメソッド layEggs();
}

関数 getSmallPet(): 魚 | 鳥 {
  // ...
}

ペットを getSmallPet() にします。
pet.layEggs(); // 通常 // 型保護の構文で使用 if ('fly' in pet) {
  ペット.飛ぶ()
} それ以外 {
  ペット.泳ぐ()
}

原理は、TypeScript の型推論をガイドし、オブジェクトの型を決定する型アサーションと同じです。

インスタンスオブ構文

ユニオン型でインターフェースの代わりにクラスを使用する場合、instanceof 構文が便利です。instanceof 構文を使用すると、異なるクラス型を区別できます。

クラス 鳥 {
  // 固有メソッド fly() {};
  // パブリックメソッド layEggs() {};
}

クラス Fish {
  // 固有メソッド swim() {};
  // パブリックメソッド layEggs() {};
}

関数 getSmallPet(): 魚 | 鳥 {
  // ...
}

ペットを getSmallPet() にします。
pet.layEggs(); // 通常 // 構文で使用 if (pet instanceof Bird) {
  ペット.飛ぶ()
} それ以外 {
  ペット.泳ぐ()
}

typeof構文

typeof 構文は、in 構文や instanceof 構文とは異なります。in 構文と instanceof 構文はどちらも、さまざまなオブジェクト型の推論を実行するために型推論をガイドするために使用されますが、typeof 構文は、基本型を推論する (または基本型とオブジェクト型を組み合わせて使用​​する) ためによく使用されます。

つまり、ユニオン型内の異なる型を区別できる場合は typeof を使用します。

関数 getSmallPet(): 数値 | 文字列 {
  // ...
}

ペットを getSmallPet() にします。
if (typeof pet === 'number') {
  ペット++
} それ以外 {
  ペット = 数字(ペット) + 1
}

要約する

フェンネル豆の 4 つの書き方の本質は依然としてフェンネル豆であるのと同様に、型保護の 4 つの書き方の本質も同じです。つまり、TypeScript の型推論を誘導して、型推論の複数選択問題を単一選択問題に変換することであり、これが型保護の本質です。

以上がTypeScriptにおける型保護の詳しい説明です。TypeScriptの型保護についてさらに詳しく知りたい方は、123WORDPRESS.COM内の他の関連記事もぜひご覧ください!

以下もご興味があるかもしれません:
  • TypeScript 列挙型
  • TypeScript の基本型の紹介
  • TypeScriptの列挙型を詳しく説明する
  • Vue プロジェクトで TypeScript クラスを適用する方法
  • TypeScriptの型保護メカニズムについての簡単な説明
  • TypeScript のクラス

<<:  docker 環境でのデータベース バックアップ (postgresql、mysql) のサンプル コード

>>:  docker を使用して influxdb と mongo をデプロイするための一般的なコマンド

推薦する

js でオブジェクトを作成するさまざまな方法とその長所と短所のまとめ

目次初期作成方法ファクトリーパターンコンストラクターパターンコンストラクタパターンの最適化プロトタイ...

テーブルの幅を固定して、テキストによって幅が変わらないように設定

ページ内のテーブルの幅を width="600px" に設定した後も、幅が固定さ...

Linux で LVGL エミュレータをコンパイルする際のエラーの解決方法

目次1. エラー現象2. エラー分析3. エラー解決1. エラー現象仮想マシンでLVGLエミュレータ...

HTML テーブル データを Json 形式に変換するサンプル コード

<table>テーブルデータをJSON形式に変換するJavaScript関数は次のとおり...

仮想マシンUbuntu 16.04がインターネットに接続できない問題の解決策

Ubuntu をインストールしたばかりですが、開いたときにネットワーク接続がありませんでした。右上隅...

HTML で選択ドロップダウン ボックスのコンテンツが不完全に表示され、部分的にカバーされる問題の解決策

今日、問題が発生しました。クエリ バーのドロップダウン ボックスの内容が長すぎて、一部が隠れてしまっ...

JS での Reduce() メソッドの使用の概要

目次1. 文法2. 例3. その他の関連方法長い間、reduce() メソッドの具体的な使い方を理解...

Vue 監視属性のグラフィック例の詳細な説明

目次リスナープロパティとは何ですか?リスニングプロパティと計算プロパティの違いは何ですか?監視プロパ...

Vue の高度な構築プロパティの詳細な説明

目次1. ディレクティブカスタムディレクティブ2. ミックスイン3. 継承を拡張する4. 提供して注...

CSSリストのスライドにより、下部に隠れるのを防ぎ、長い画面モデルの処理に適応します。

1. モバイル端末がリストスライドを処理するとき、WeChat には下部にページに戻るボタンが組み...

IIS web.config でクロスドメイン アクセスを設定する方法

要件: ページに画像を表示する必要がありますが、さまざまな理由により、画像はサーバー 2 にあります...

React Native が「NSArray<id<RCTBridgeModule>>型のパラメータを初期化できません」というエラーを報告する (解決方法)

最近、古い RN プロジェクトを Xcode で実行すると、次のコード エラーが報告されました。 &...

Windows での MySQL の詳細なインストール手順と基本的な使用方法

目次1. MySQLをダウンロードする2. MySQLをインストールする3. MySQL の基本的な...

CSS の Flex レイアウトを使用してシンプルな縦棒グラフを作成する方法

以下は、Flex レイアウトを使用した棒グラフです。 HTML: <div class=&qu...

VueプロジェクトにPWAを導入する手順

目次1. 依存関係をインストールする2. vue.config.js ファイルで pwa を設定しま...