web-dev-qa-db-ja.com

TypeScript instanceofが機能しない

Instanceof演算子の使用に問題があり、動作しないようです。これが私のコードの一部です:

        const results = _.map(items, function(item: Goal|Note|Task, index: number) { 
            let result = {};
            if (item instanceof Goal) {
                result = { id: index, title: item.name };
            } else if (item instanceof Note) {
                result = { id: index, title: item.content.text };
            } else if (item instanceof Task) {
                result = { id: index, title: item.name };
            }

            console.log(item);
            console.log(item instanceof Goal);
            console.log(item instanceof Note);
            console.log(item instanceof Task);

            return result; 
        });

すべてのログにfalseと表示されます。コンソールは次のようになります。

No type matched

3つのタイプのみが可能であることを明示しているにもかかわらず、それらのどれも一致しません。タイプ名がGoalのオブジェクト自体も表示されるため、instanceof Goalと一致しない理由はわかりません。

何か案は?

7
AnimaSola

instanceofは、作成元の関数またはクラスと一致する場合にのみtrueを返します。ここのitemは単純なObjectです。

const a = { a: 1 } // plain object
console.log(a);

// {a:1}                 <-- the constructor type is empty
//   a: 1
//   __proto__: Object   <-- inherited from

a instanceof A         // false because it is a plain object
a instanceof Object    // true because all object are inherited from Object

コンストラクター関数またはクラスを使用して構築されている場合、instanceofは期待どおりに機能します。

function A(a) {
    this.a = a;
}

const a = new A(1);    // create new "instance of" A
console.log(a);

// A {a:1}               <-- the constructor type is `A`

a instanceof A         // true because it is constructed from A
a instanceof Object    // true

GoalInterfaceである場合、オブジェクトのタイプではなく構造のみをチェックします。 Goalがコンストラクターの場合、instanceofチェックに対してtrueを返す必要があります。

次のようなものを試してください:

// interface Goal {...}
class Goal {...}        // you will have to change the way it works.

items = [
   new Goal()
];
14
Gopikrishna S

タイプガードを使用することもできます。

https://basarat.gitbooks.io/TypeScript/docs/types/typeGuard.html

https://www.typescriptlang.org/docs/handbook/advanced-types.html

たとえば、クラスにリテラルタイプガードを使用する場合:

class Goal {
 type: 'goal'
...
}

その後、チェックは次のように簡単です:

if (item.type === 'goal') {
}

または、独自のタイプガードを作成することもできます。

function isNote(arg: any): arg is Note {
    // because only your Note class has "content" property?
    return arg.content !== undefined;
}

if (isNote(item)) {
    result = { id: index, title: item.content.text };
}
2
AFD

コンストラクタでオブジェクトをインスタンス化してみてください。テスト目的で手動でオブジェクトをモックしたため、同じことが起こりました。次の例のようにアイテムを作成すると、機能するはずです。

item: Goal = new Goal(*item values*)
0
Lucia