Reputation: 8091
Okay strange title, not sure how else to put it. So this is the problem. I was under the impression that if I pass in the subtype of the parent constructor property, to the child constructor property everything will work. However, that is not the case. If I try to use the subtype method on the child property I get an error.
interface IDataMaper{
save():void
}
interface IReactiveDataMapper extends IDataMaper{
saveReactive():void
}
class A {
constructor(protected mapper: IDataMaper) {}
}
class B extends A {
constructor(mapper: IReactiveDataMapper) {
super(mapper)//no errror here
// this.mapper.saveReactive() //error
}
}
Upvotes: 1
Views: 220
Reputation: 51093
Lukas's answer gives a good explanation of why this error occurs; the type of this.mapper
is IDataMapper
, not the more specific type IReactiveDataMapper
.
As an alternative solution which doesn't require changing the type of the field or declaring a new field with a different type, you can call the method on the parameter mapper
, which references the same object as this.mapper
but has the more specific type:
class B extends A {
constructor(mapper: IReactiveDataMapper) {
super(mapper);
mapper.saveReactive(); // instead of this.mapper
}
}
This option may be simpler if you only need the more specific type in the constructor, as in your example. If you need this.mapper
to have the more specific type in other methods in the subclass, then Lukas's answer is the best way.
Upvotes: 0
Reputation: 3909
The problem is that you are accessing the mapper
instance from the this
context. Note the protected mapper: IDataMapper
in the constructor of class A. By prepending the keyword protected
there, you enforce that the class A will have a protected member called mapper
of the type IDataMapper
. In the constructor of B, you do not have the keyword protected
, meaning that the protected member mapper
of B's this
-context is not overwritten, and the IDataMapper
-property stored by A is used. Add a protected
-prefix to the variable in B's constructor to have it overwrite the member and you will not experience the error.
interface IDataMaper{
save():void
}
interface IReactiveDataMapper extends IDataMaper{
saveReactive():void
}
class A {
constructor(protected mapper: IDataMaper) {}
}
class B extends A {
constructor(protected mapper: IReactiveDataMapper) {
super(mapper);
this.mapper.saveReactive();
}
}
Upvotes: 1