TypeScript で実行時にオブジェクトタイプを確認する

Migel Hewage Nimesha 2024年2月15日
  1. TypeScript の主なタイプ
  2. TypeScript で実行時にクラスタイプを確認する
  3. TypeScript でランタイムのインターフェイスタイプを確認する
TypeScript で実行時にオブジェクトタイプを確認する

この記事では、TypeScript で実行時にオブジェクトタイプを確認する方法について説明します。

TypeScript の主なタイプ

TypeScript は厳密に型指定された言語です。したがって、コンパイル時にタイプをチェックし、ランタイムエラーを減らします。

TypeScript には、次のようにいくつかの主要なタイプがあります。

  • 文字列、数値、ブール値などのプリミティブタイプ
  • カスタムクラスタイプ
  • インターフェースタイプ
  • ユニオンタイプ
  • エイリアスを入力します

TypeScript で実行時にクラスタイプを確認する

TypeScript は、EcmaScript 6 の class キーワードをサポートしています。これを使用して、OOP 方式でコードを記述できます。

クラス Engineer を作成しましょう。

class Engineer {
}

このクラスにはプロパティや動作が含まれていないため、メソッドを追加しましょう。

class Engineer {
    visitSite(): void {
        console.log("This is the Engineer class");
    }
}

次のように、別のクラス Doctor を取得したとします。

class Doctor {
    visitWard(): void {
        console.log("This is the Doctor class");
    }
}

EngineerDoctor は 2つのユーザー定義タイプです。一部のシナリオでは、既存のオブジェクトタイプが Engineer または Doctor クラスに属しているかどうかを確認する必要があります。

これは、TypeScript の instanceof 演算子を使用すると非常に簡単です。

instanceof 演算子を使用してクラスタイプを確認する

指定されたオブジェクトが TypeScript クラスのインスタンスであるかコンストラクターであるかをチェックします。マルチレベルの継承を考慮して、関連するクラスが別のレベルに表示されるかどうかを確認します。

一致するクラスが見つかると、true が返されます。それ以外の場合は、false を出力します。

構文:

my_object instanceof my_custom_class_type

この演算子を使用して、TypeScript ロジック内の Engineer クラスと Doctor クラスを区別してみましょう。

まず、新しいチェッカー関数 checkObjectType() を作成します。

function checkObjectType(myObject) {
    if (myObject instanceof Engineer) {
        myObject.visitSite()
    }
    if (myObject instanceof Doctor) {
        myObject.visitWard()
    }
}

上記のチェッカー関数では、myObject のクラスをチェックします。結果に基づいて、所属するクラスメソッド visitSite() または visitWard() を呼び出します。

両方のクラスからオブジェクトを開始し、オブジェクトを checkObjectType メソッドに渡します。

let engineerObject: Engineer = new Engineer;
let doctorObject: Doctor = new Doctor;
checkObjectType(engineerObject);
checkObjectType(doctorObject);

出力:

TypeScript ランタイムタイプチェック出力 1

予想どおり、TypeScript は、提供された各オブジェクトの正しいクラスを識別します。

TypeScript でランタイムのインターフェイスタイプを確認する

instanceof を使用して、指定されたインスタンスがクラスに属しているかどうかを確認できます。ただし、これは TypeScript インターフェイスタイプまたはタイプエイリアスでは機能しません。

実行時に、これらのインターフェイスタイプはすべてなくなります。したがって、通常の JavaScript の typeof 演算子は、出力をオブジェクトとして提供します。

次のように、AirplaneCar の 2つのインターフェースを定義しましょう。

interface Airplane {
    hasWings() {
        console.log("2 wings");
    }
}

interface Car {
    hasWheels() {
        console.log("4 wheels");
    }
}

次に、TypeScript ユーザー定義のタイプガードを作成して、指定されたオブジェクトが Airplane または Car タイプに属しているかどうかを確認し、オブジェクトを互換性のあるタイプに絞り込みます。ここでは、戻り型として型述語を使用する必要があります。

タイプ述語の構文:

my_parameter_name is custom_type

my_parameter_name は、関数に渡される現在の引数である必要があります。この場合、custom_typeAirplane または Car になります。

2つのタイプのガードを定義しましょう:

function isAirplane(anyObject: any): anyObject is Airplane {
    return (anyObject as Airplane).hasWings() !=== undefined;
}

渡されたオブジェクト anyObjecthasWings() メソッドが使用可能かどうかをチェックすることにより、オブジェクトの形状がインターフェイスの形状と同等であることを確認します。次に、オブジェクトを Airplane タイプに絞り込むタイプ述語を返します。

同様に、isCar() 関数を実装できます。

function isCar(anyObject: any): anyObject is Car {
    return (anyObject as Car).hasWheels() !=== undefined;
}

最後に、testType() 関数を実装してコードをテストできます。

let car: Car = {wheels: 4};
let flight: Airplane = {wings: 2};

function testType(obj: any) {
  if (isAirplane(obj)) {
    // 'obj' is narrowed to type 'Airplane'
    console.log("Airplane wings: "+ obj.wings);
  }
  else if (isCar(obj)) {
    // 'obj' is narrowed to type 'Car'
     console.log("Car wheels: "+ obj.wheels);
  }
}

testType(car);
testType(flight);

出力:

TypeScript ランタイムタイプチェック出力 2

ユーザー定義のタイプガードを使用すると、実行時にインターフェイスの正確なタイプを確認できます。

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.

関連記事 - TypeScript Type