0

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

2 Answers 2

2

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.
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for teaching me about generic constraints, that should do the job!
Actually, that doesn't work, unless I'm missing something. Now I need to declare Layers with a type, but that's not what I want to do, because at declaration time I don't know the type, ie "let layer = new Layer(valueRaster);" doesn't work, it expects "new Layer<ValueRaster>(valueRaster);"
0

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.