TypescriptのInterfaceにはinstanceofは使えない。
Typescriptには、JavaやC#と同じ様にinterfaceがあります。
が、JavaやC#と同じ様に扱うと怪我をします。
instanceofでinterfaceは使えない。
最初に私がビックリした事です。JavaやC#では'instanceof IAction
を定義してActionというクラスで実装して見ます。それをinstaceof IAction
でチェックしてみると、、、
interface IAction { dosomething(): void; } class Action implements IAction { dosomething() { console.log('hoge'); } } if (Action instanceof IAction) { // something to do }
VScodeを使っていれば、if文の'IAction'の箇所でインテリセンスによってエラーが出ます。
[ts] 'IAction' only refers to a type, but is being used as a value here.
訳すと、IActionは型としてしか参照出来ません、ここでは値として参照されています。。。
これはどういう事でしょうか?JavaやC#脳の人にとっては混乱するエラー文です。
instanceof はタイプ、型で検査するのだから合っているのでは?値として参照とはどういう事?
コレが何故ダメなのか、すぐに分かる方法があります。
試しにIAction
の例のif文の部分を削除して、Javascriptにコンパイルしてみましょう。
すると↓の様になります。
var Action = /** @class */ (function () { function Action() { } Action.prototype.dosomething = function () { console.log('hoge'); }; return Action; }());
なんと、Javascript変換すると'IAction'は存在しなくなっています!
これで何故interface
でinstanceof
が使えないのか分かった様な気がします。
interface
をinstanceof
で比較しようにも、Javascript上に存在しないので比較出来ません。
そして、型とはJavascriptに変換後と評価出来ないもの、値とはJavascriptに変換後も評価可能なものと言えます。
というわけで、どうあがいてもTypescriptのinterface
ではinstaceof
を使った型チェックをする事が出来ません。
どうしてもinstanceof
を使いたいという人はinterfaceではなくclassを使うしかないでしょう。classはjavascript変換後にも残りますし、Typescript上でも型としても認識されます。抽象classを上手く使えば良いかも。
abstract class BaseAction { abstract dosomething(): void; } class Action extends BaseAction { dosomething() { console.log('hoge'); } } if (Action instanceof BaseAction) { // true // something to do }