22

All of our typescript classes inherit (directly or indirectly) from:

export class WrObject {
    className:string;

    public instanceOf(name : String) : boolean {
        return this.className === name;
    }
}

We then declare a subclass as:

export class Section extends WrObject {
    public static CLASS_NAME = 'Section';
    className = Section.CLASS_NAME;

        public instanceOf(name : String) : boolean {
            if (this.className === name)
                return true;
            return super.instanceOf(name);
        }

}

And you can then check with:

if (obj.instanceOf(Section.CLASS_NAME))

It all works great. However, I think it would be cleaner if we could do:

if (obj.instanceOf(Section))

Is there any way to do that? Or any suggestions as to a better approach?

thanks - dave

David Thielen
  • 28,723
  • 34
  • 119
  • 193

3 Answers3

39

If you are willing to accept the prototypal nature of JavaScript you can just use instanceof which checks the prototype chain:

class Foo{}
class Bar extends Foo{}
class Bas{}

var bar = new Bar();

console.log(bar instanceof Bar); // true
console.log(bar instanceof Foo); // true
console.log(bar instanceof Object); // true

console.log(bar instanceof Bas); // false
basarat
  • 261,912
  • 58
  • 460
  • 511
  • I thought (can't find the post here now) that using instanceof was discouraged in typescript as being inaccurate. Did I misunderstand the other threads? – David Thielen Jul 12 '14 at 13:34
  • 1
    depends. You're not planning on using `instanceof` on a `null` are you ? ;) + its unreliable between iframes (its not the same `Foo.prototype` in each frame if you check by reference which is what this is doing underneath). Probably same issue in webworkers but I am not sure – basarat Jul 12 '14 at 13:39
  • With nulls - no. In web workers - yes everywhere. And it's with objects created in one thread, posted to another thread, and in the receiving thread we assign proto to turn the received data back into an object. – David Thielen Jul 12 '14 at 13:42
  • if `foo.__proto__ == Foo.prototype` then its okay. That is what `instanceof` does (or parent i.e. `__proto__.__proto__` till null) – basarat Jul 12 '14 at 13:43
2

You can do it. Just replace your instanceOf implementation with this one:

public instanceOf(cls: { CLASS_NAME: string; }) {
    return cls.CLASS_NAME === this.className || super.instanceOf(cls);
}
Igorbek
  • 31
  • 2
  • 4
    Beware the fact that classes in different namespaces with the same name could be an issue. Programming.Parent and Genealogy.Parent are very different classes in different inheritance trees and namespaces, but would falsely test true here because their string names match. – Myrddin Emrys Jul 08 '16 at 20:05
0

I guess this might work Example on Playground

var getName = function(obj) : string { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec(obj);
   return (results && results.length > 1) ? results[1] : "";
};

class Foo
{

}

function IsTypeOf(obj: any, type: Function)
{
    alert(obj.constructor.name + " == " + getName(type));
}

IsTypeOf(new Foo(), Foo);

Related

Community
  • 1
  • 1
BrunoLM
  • 97,872
  • 84
  • 296
  • 452