TypeScript 类继承构造函数混淆

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40433555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:59:36  来源:igfitidea点击:

TypeScript class inheritance constructor confusion

javascriptclassoopinheritancetypescript

提问by Christian Todd

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.

我正在阅读 Eloquent Javascript 这本书,并且在章节练习结束时遇到了一些障碍。我很早就决定我将主要使用 TypeScript 在 vanilla JS 之上解决这些练习,只是为了让自己接触 TS 为我提供的额外功能。

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

完整的练习可以在这里找到: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:

在我看来,我应该基本上扩展作者在本章中定义的预先存在的类,我已尽力在 TypeScript 中重写以利用类:

//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 textis being coerced into a different type and causing this error to be thrown.

我目前根本没有得到任何输出,而是得到:TypeError: text.split is not a function. 我知道我收到此错误是因为我试图在字符串以外的类型上调用 .split(),但我不确定在我的代码中的哪个位置text被强制转换为不同的类型并导致此错误被抛出。

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.

我偷偷怀疑我的问题出在类的构造函数中,但我不清楚。对我的代码组成的任何见解将不胜感激。这也是我第一次使用 TypeScript 类和继承,所以期待一些新手错误。

回答by artem

This code in extension class constructor

扩展类构造函数中的这段代码

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

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

通过text调用直接传递给预先存在的类构造函数super(text)。所以text这里应该是一个字符串,因为它是在预先存在的TextCell构造函数中声明的。

But when you create instance of StretchCellclass, you are passing TextCellobject instance for textparameter, not a string. This is the reason for text.split is not a functionerror - TextCellhas no method called split.

但是当您创建StretchCell类的实例时,您传递的是TextCell对象实例作为text参数,而不是字符串。这就是text.split is not a function错误的原因-TextCell没有调用方法split

The extension class constructor should be declared as

扩展类构造函数应声明为

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

and StretchCellinstance has to be created like this:

并且StretchCell必须像这样创建实例:

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