This might be a stupid question as I'm new to typescript, however, I have the following scenario. I have an array that contains objects that all extend the same class. For example:
class Body{
// implementation
}
class Rectangle extends Body{
// implementation
}
class Circle extends Body{
// implementation
}
const box: Rectangle = new Rectangle()
const circle: Circle = new Circle()
const world: Array<Body> = [box, circle]
The problem I have is that when I am accessing methods on the elements in the array, I'm getting an error that they don't exist on the Body class (which they don't). I'm wondering if there is a correct way to do this or if I am doing something completely wrong?
CodePudding user response:
Array<Body>
says that the array elements are only guaranteed to implement the Body
interface.
If you want to have an array of Body
instances that might be subclasses, then you have to do a runtime check first to make sure the object is what you expect it to be.
const world: Array<Body> = [box, circle]
if (world[0] instanceof Rectangle) {
world[0].someRectangleOnlyMethod()
}
This is required because this would crash since that method wouldn't exist on Circle
instances:
world[1].someRectangleOnlyMethod() // crash
CodePudding user response:
You should try to create abstract methods in the Body
class that can be implemented by subclasses. This way you would have different behaviour but same methods - polymorphism. F.e.:
abstract class Body {
abstract area(): number;
}
and then subclasses can have the implementation.
If it does not make sense to have same method names in different classes, then you must check the object's class with instanceof
as Alex Wayne said.
CodePudding user response:
Though in most cases you do want either Alex Wayne's or Uroš Anđelić's approaches, there is also
const world = [box, circle] as const;
in which case the type of world
will be inferred as [Box, Circle]
and you can call Box
's methods on world[0]
.