Typescript Classes 10 exercises
solution

Inheriting Properties from Other Classes in TypeScript

Alright, let's initiate our new Shape class.

The first thing to do is to move the private properties x and y, as well as the position getter and move method from CanvasNode to Shape:


class Shape {
#x: number;
#y: number;
constructor(options?: { x: number; y: num

Loading solution

Transcript

00:00 Okay, let's create our new Shape class. So we have Class, Shape. Lovely. A nice empty class, nothing in it. Let's now fill it with stuff. We've got our X and Y, our private properties, and you can immediately see that moving those in has caused a whole load of other issues.

00:17 We can see that we can just pretty much move Position and Move into here. That's nice. But we also need to assign these in the Constructor. So let's copy over this Constructor and just remove the stuff we don't need. We don't need ViewMode anymore. That doesn't make sense to receive in the options, so let's delete that here.

00:35 We can also remove X and Y down from here too inside the CanvasNode. And now CanvasNode is pretty much just the ViewMode stuff. That's fabulous. But we can see in the tests here that CanvasNode.Position no longer exists on here. CanvasNode.Move also doesn't exist.

00:54 So we need to find a way to make this CanvasNode extend or inherit from the Shape and add in a bunch of Shape properties. So let's say CanvasNode extends Shape. And similar to interfaces, this means that CanvasNode now inherits all the properties and methods of Shape.

01:12 So Shape is now just a pure Shape and a CanvasNode is something that we can actually render to the Canvas. But this hasn't solved all our issues. We now have a bunch of stuff happening. Let's actually check out the error down below. We can see that now CanvasNode, it's only expecting ViewMode to be passed in the options because we removed X and Y from there.

01:31 So we can see here that argument of type XNumber, YNumber is not assignable to parameter of type ViewMode, ViewMode are undefined. We need to add XNumber and YNumber and then put them in to our options inside our CanvasNode Constructor.

01:46 So you notice that it doesn't automatically kind of like sync up just because it extends Shape doesn't mean it has any impact on this Constructor options here. Let's hover over Constructor or hover over this error that we're getting inside the Constructor. Constructors for derived classes must contain a super call.

02:04 A super call, eh? Well, it turns out that when we are initializing our Shape here, it doesn't automatically kind of like call each Constructor. What you have to do is inside this Constructor, you have to call super.

02:19 And what super does is it runs the Constructor for the Shape above it or from the thing that it's extending from. So if we don't have this, then there's no need for this super. Super can only be referenced in a derived class.

02:33 So as soon as you extend from something, this is now a derived class and it's ready to receive super. But what does super actually receive? Well, we can see that we're calling, if we hover over super, we're calling the Constructor Shape and it needs to be passed in the options there. And the options are X and Y.

02:51 And currently, because Shape doesn't require options, it's not yelling about anything. But this will actually break because we need to pass in options X and Y. Otherwise, it's going to error and yell at us further down the line.

03:04 In fact, we can see that it's actually failing in our tests because we can see that shouldBeAbleToReceiveInitialPosition is failing. It's expecting to receive X and Y, 1 or 10 and 20, but it's in fact just receiving X, 0, Y, 0. That's because we're not passing in the argument to the super. Let's just look at that test.

03:23 There you go, shouldBeAbleToReceiveInitialPosition. The position isn't being set because we're not passing this argument of X and Y into the super. But as soon as we do, let's just pass in options there, now it starts passing.

03:37 It starts working because we've initialized the base class with the things that it needs using super. Fantastic stuff. So here we go. We've basically just refactored our class here so that we now have a shape that's our base class. We can stick this in another file if we want to.

03:54 And we have our canvas node which extends from that base class. So here we go. We're getting into pure object-oriented stuff. Inheriting from different classes and understanding the behavior is attached to different objects. It's really, really cool and I really like that you can do this in TypeScript.