1. ホーム
  2. javascript

[解決済み] Typescript によるインターフェース型チェック

2022-03-20 05:48:10

質問

この質問は TypeScriptによるクラス型チェック

any型の変数があるインターフェースを実装しているかどうかを実行時に調べる必要があります。以下は私のコードです。

interface A{
    member:string;
}

var a:any={member:"foobar"};

if(a instanceof A) alert(a.member);

このコードをタイプスクリプトのプレイグラウンドに入力すると、最後の行に "The name A does not exist in current scope" というエラーマークが表示されるでしょう。しかし、それは真実ではなく、名前は現在のスコープに存在するのです。変数の宣言を次のように変更することもできます。 var a:A={member:"foobar"}; エディタから文句を言われることもなく WebをブラウズしてSOの他の質問を見つけた後、私はインターフェイスをクラスに変更しましたが、その後、インスタンスを作成するためにオブジェクトリテラルを使用することはできません。

Aという型がどうして消えるのか不思議でしたが、生成されたjavascriptを見ると問題がよくわかります。

var a = {
    member: "foobar"
};
if(a instanceof A) {
    alert(a.member);
}

Aはインターフェースとして表現されていないため、実行時の型チェックはできません。

動的言語であるjavascriptにはインターフェースの概念がないそうですね。インターフェイスの型チェックをする方法はないのでしょうか?

typescript playgroundのオートコンプリートによると、typescriptにはメソッドまで用意されていることがわかります。 implements . どうすれば使えるの?

解決方法は?

を使わなくても、やりたいことは実現できます。 instanceof というキーワードで、カスタムのタイプガードを書くことができるようになりました。

interface A{
    member:string;
}

function instanceOfA(object: any): object is A {
    return 'member' in object;
}

var a:any={member:"foobar"};

if (instanceOfA(a)) {
    alert(a.member);
}

たくさんのメンバー

オブジェクトが型にマッチするかどうかを判断するために多くのメンバーをチェックする必要がある場合は、 代わりに識別子を追加することができます。下の例は最も基本的なもので、自分で識別子を管理する必要があります。 識別子の重複を避けるためには、もっと深くパターンを理解する必要があります。

interface A{
    discriminator: 'I-AM-A';
    member:string;
}

function instanceOfA(object: any): object is A {
    return object.discriminator === 'I-AM-A';
}

var a:any = {discriminator: 'I-AM-A', member:"foobar"};

if (instanceOfA(a)) {
    alert(a.member);
}