Reputation: 201
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
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
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