I have these two Typescript classes:
class Base {
value: string;
lambdaExample = () => {
this.value = 'one';
}
methodExample() {
this.value = 'two';
}
}
class Child extends Base {
lambdaExample = () => {
super.lambdaExample(); // Error, because I've overwritten (instead of overridden) the method
this.value = 'three'; // ok
}
methodExample() => {
super.methodExample(); // ok
this.value = 'four'; // Error: this refers to window, not to the actual this
}
}
How do I write my methods in such a way that this
references are reliable, and I can override methods and call them from the parent class?
When a method is marked with override , TypeScript will always make sure that a method with the same name exists in a the base class. This member cannot have an 'override' modifier because it is not declared in the base class 'SomeComponent'.
When overriding a method, you might want to use the @Override annotation that instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, then it will generate an error.
To override an inherited method, the method in the child class must have the same name, parameter list, and return type (or a subclass of the return type) as the parent method. Any method that is called must be defined within its own class or its superclass.
Using protected is the correct way to solve this! But if you have no access to the parent class (e.g. because it is within a library) you also could overwrite private class member-function in the constructor.
There's actually a good look at the different ways of tackling this problem on Microsoft's Git Wiki. It essentially comes down to this:
There are many more stipulations in the actual Wiki and I really recommend you read the whole thing.
EDIT
An example of wrapping:
Given the class
class SomeClass {
public someProp: string = "Hello World";
public someMethod() {
console.log(this.someProp);
}
}
If you were to call someMethod
from (for example) a click handler - someEl.onclick = instanceOfMyClass.someMethod;
- an exception would be raised (assuming window
doesn't have a property someProp
).
You can circumvent this by either binding the function to instanceOfMyClass
(not type-safe, not ES6 compatible) or by manually wrapping it (effectively what bind is doing, anyway):
someEl.onclick = function() {
someInstanceOfMyClass.someMethod();
};
It's a little bit verbose and pedantic, but by calling someMethod
as a property of someInstanceOfMyClass
and not passing it into an event handler (which turns it into a property of window
) you ensure that this
is always an instance of MyClass
.
Your assumptions about the reasons for the errors are wrong, which I think is the cause of your problem...at least as I understand it.
lambdaExample = () => {
this.value = 'one';
}
This line, for example is defining a property, not a method on Base
, and you can't override a property. The only instance method you've defined in Base
is methodExample
.
In Child
, you're assigning a new variable to lambaExample
. Your call to super.lambaExample()
fails because that can only access methods via super()
; accessing properties is done via this
. methodExample
in your Child
class shows up as a syntax error for me.
Note that you can still call super from Child
in the overwritten lambaExample
property, but only on methods. This works:
lambdaExample = () => {
super.methodExample(); // Success on super.<somemethod>()
this.value = 'three';
}
I'm only aware of one way to declare an instance method in a class, and if you're consistent with that syntax, this
works as you would expect:
class Base {
value: string;
lambdaExample() {
this.value = 'one';
}
methodExample() {
this.value = 'two';
}
}
class Child extends Base {
lambdaExample() {
super.lambdaExample();
this.value = 'three';
}
methodExample() {
super.methodExample();
this.value = 'four';
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With