最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - TypeScript class inheritance constructor confusion - Stack Overflow

programmeradmin1浏览0评论

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: .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.

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.

Share Improve this question asked Nov 5, 2016 at 0:29 Christian ToddChristian Todd 2461 gold badge3 silver badges14 bronze badges 1
  • Your creating an instance of StretchCell, the first parameter is a TextCell object, your super is expecting a string. on StretchCell you have constructor(text: any is it text, or is it anything. ? Because your super(text) is expecting a string. – Keith Commented Nov 5, 2016 at 0:38
Add a comment  | 

1 Answer 1

Reset to default 15

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);
发布评论

评论列表(0)

  1. 暂无评论