Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript class inheritance constructor confusion

I'm working through the book Eloquent Javascript and I've hit a bit of a snag with an end of chapter exercise. I decided early on that I would use TypeScript primarily to tackle these exercises on top of vanilla JS just to expose myself to the extra features TS affords me.

The full exercise can be found here: http://eloquentjavascript.net/06_object.html#h_nLNNevzcF7

As I see it, I'm supposed to essentially extend a pre-existing class that has been defined by the author within this chapter which I have done my best to re-write in TypeScript to leverage classes:

//from textbook.

function repeat(string: string, times: number): string {
    var result = '';
    for (var i = 0; i < times; i++)
        result += string;
    return result;
}

//inferred from textbook.

class TextCell {
    text: any;
    constructor(text: string) {
        this.text = text.split('');
    }
    minWidth(): number {
        return this.text.reduce((width: number, line: any) => Math.max(width, line.length), 0);
    }
    minHeight(): number {
        return this.text.length;
    }
    draw(width: number, height: number) : any[]{
        var result: any[] = [];
        for (var i = 0; i < height; i++) {
            var line = this.text[i] || '';
            result.push(line + repeat(' ', width - line.length));
        }
        return result;
    }
}

And here is my extension of that class:

class StretchCell extends TextCell {
    width:  number;
    height: number;
    constructor(text: any, width: number, height: number) {
        super(text);
        this.width  = width;
        this.height = height;
    }

    minWidth(): number {
        return Math.max(this.width, super.minWidth());
    }
    minHeight(): number {
        return Math.max(this.height, super.minHeight());
    }
    draw(width: number, height: number): any[] {
        return super.draw(this.width, this.height);
    }
}

The 'tests' that are run are:

var sc = new StretchCell(new TextCell('abc'), 1, 2);

console.log(sc.minWidth());
// → 3
console.log(sc.minHeight());
// → 2
console.log(sc.draw(3, 2));
// → ['abc', '   ']

I'm not currently getting any output at all, instead I'm getting: TypeError: text.split is not a function. I know I'm getting this error because I'm attempting to call .split() on a type other than a string, but I'm not sure where in my code that the text is being coerced into a different type and causing this error to be thrown.

I have a sneaking suspicion that my issue lies within the constructors of the classes, but it's unclear to me. Any insight into the composition of my code would be greatly appreciated. This is also my first time using TypeScript classes and inheritance, so expect some newbie mistakes.

like image 898
Christian Todd Avatar asked Nov 05 '16 00:11

Christian Todd


People also ask

Is constructor inherited in TypeScript?

We inherit constructor functionality with the super() constructor. If the parent class constructor has any parameters, the super() constructor will need the same parameters.

What is the correct way of inheriting in TypeScript?

The TypeScript uses class inheritance through the extends keyword. TypeScript supports only single inheritance and multilevel inheritance. It doesn't support multiple and hybrid inheritance. We can declare a class inheritance as below.

Does TypeScript support inheritance?

TypeScript supports single inheritance and multilevel inheritance. We can not implement hybrid and multiple inheritances using TypeScript. The inheritance uses class-based inheritance and it can be implemented using extends keywords in typescript.

Can a constructor be inherited by a derived class from the base class?

In inheritance, the derived class inherits all the members(fields, methods) of the base class, but derived class cannot inherit the constructor of the base class because constructors are not the members of the class.


1 Answers

This code in extension class constructor

constructor(text: any, width: number, height: number) {
    super(text);

passes text directly to pre-existing class constructor by calling super(text). So text here is supposed to be a string, because that's how it's declared in pre-existing TextCell constructor.

But when you create instance of StretchCell class, you are passing TextCell object instance for text parameter, not a string. This is the reason for text.split is not a function error - TextCell has no method called split.

The extension class constructor should be declared as

constructor(text: string, width: number, height: number) {
    super(text);

and StretchCell instance has to be created like this:

var sc = new StretchCell('abc', 1, 2);
like image 136
artem Avatar answered Oct 15 '22 04:10

artem