christian.stock
christian.stock

Reputation: 201

Typescript doesn't recognise polymorphism class

I have a class defined like this:

export class Layer
{
    public raster: BaseRaster;

    constructor(raster: BaseRaster)
    {
       this.raster = raster;
    }  
}

I got an abstract class

export abstract class BaseRaster
{
    public doBasicStuff(): void { ... }
}

I got multiple Raster classes: ie

export class ValueRaster extends BaseRaster
{
   public doMoreStuff(): void { ... }
}

export class ZoneRaster extends BaseRaster
{
   public doMoreStuff(): void { ... }
}

When I do

let valueRaster = new ValueRaster();
let layer = new Layer(valueRaster);

layer.raster.doMoreStuff(); // fails!

layer.raster will be of type BaseRaster - which is not how other languages work.

The issue I'm having is that layer.raster.doMoreStuff() isn't part of BaseRaster and hence fails.

I've resorted to doing type checks:

if (layer.raster.constructor.name === 'ValueRaster')
{
    (layer.raster as ValueRaster).doMoreStuff();
}
else if (layer.raster.constructor.name === 'ZoneRaster')
{
    (layer.raster as ZoneRaster).doMoreStuff();
}

which works, but is cumbersome.

Can I get the polymorphism to work properly in Typescript? Ie if I'd do the same in Java/C++/C#, calling layer.raster.doMoreStuff() would work, because it keeps the class type when constructing Layer (oddly enough Typescript knows the constructor name, but doesn't keep the class).

Upvotes: 0

Views: 274

Answers (2)

christian.stock
christian.stock

Reputation: 201

Turns out I made a mistake in declaring BaseRaster. Here's the correct code:

export abstract class BaseRaster
{
    public doBasicStuff(): void { ... }

    abstract public doMoreStuff(): void;
}

layer.raster.doMoreStuff(); // works!

Upvotes: 0

Shanon Jackson
Shanon Jackson

Reputation: 6531

Confused as to what you want, if you want some type that is a superset of BaseRaster then you type that with a generic constraint like so...

There's a few classes missing from this post so i took the liberty of creating some fake ones for this example.

class BaseRaster {
  baseRasterMethod() {
    return "hello"
  }
}

class BaseClass extends BaseRaster {}

export class Layer<T extends BaseRaster> {
    public raster: T;

    constructor(raster: T)
    {
       this.raster = raster;
    }

}

export class ValueRaster extends BaseClass
{
   public newFunction() {
     return "newFunction"
  }
}

let valueRaster = new ValueRaster();
let layer = new Layer(valueRaster);
layer.raster.newFunction // works.

Upvotes: 2

Related Questions