I have a an abstract class FooObject. Only two children ever inherit FooObject, lets call them ThisFooObject and ThatFooObject.
I'm looking for a performant way to turn a FooObject into whichever child it is. In this case, that means not using instanceof - which performs at <10% the speed of a boolean lookup.
The way I've investigated is something like this:
FooObject.ts
import ThisObject from "./ThisObject";
import ThatObject from "./ThatObject";
abstract class FooObject {
isThisObject() : this is ThisFooObject {
// Either check for ThisFooObject properties, or override this
// in the ThisFooObject class to always return true.
return duckTypingTest();
}
// ditto here
isThatObject() : this is ThatFooObject {}
}
I understand that this is not pretty. It's not a scalable approach if I have more children of FooObject - and it requires the parent to know about the children in a kinda encapsulation breaking way. But in my specific case, I'm willing to put up with this if it avoids me having to do 'instanceof'.
On the bright side, when I have a reference to a FooObject, and I want to something when it's a ThatFooObject, I can do something like:
fooObjects.forEach( foo => {
// Foo currently typed as a FooObject
if(foo.isThatObject()){
// Foo now typed as a ThatFooObject
foo.magic+=10
}
});
This is all works - with one little caveat - I have to be careful to get the import order correct. IE, in my main.ts entry point, do something like
import 'ThatFooObject';
import 'FooObject';
But other than that, I'm fairly well pleased with this pattern. The issue comes when I try this with more than one child. I start to get issues with circular dependencies throwing things off, and errors like class extends value undefined is not a constructor or null.
I can't figure out how to make this work. Am I just barking up the wrong tree, and I should do this a much simpler way?