Home > Enterprise >  How can I assign types for an array of objects that extend the same class?
How can I assign types for an array of objects that extend the same class?

Time:06-02

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

Playground

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].

  • Related