web-dev-qa-db-ja.com

TypeScriptクラス継承コンストラクターの混乱

私はEloquentJavascriptの本を読んでいますが、章の終わりの演習で少し問題が発生しました。私は早い段階で、TSが提供する追加機能に自分自身をさらすために、主にVanillaJSの上でこれらの演習に取り組むためにTypeScriptを使用することを決定しました。

完全な演習はここにあります: http://eloquentjavascript.net/06_object.html#h_nLNNevzcF7

私が見ているように、私は基本的に、この章内で作成者によって定義された既存のクラスを拡張することになっています。これは、クラスを活用するために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;
    }
}

そして、これがそのクラスの私の拡張です:

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);
    }
}

実行される「テスト」は次のとおりです。

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', '   ']

現在、出力がまったく得られていません。代わりに、次のようになっています。TypeError: text.split is not a function。文字列以外の型で.split()を呼び出そうとしているため、このエラーが発生することはわかっていますが、コードのどこでtextが強制的に変換されているのかわかりません。タイプが異なり、このエラーがスローされます。

私の問題はクラスのコンストラクターにあるのではないかとこっそり疑っていますが、それは私にはわかりません。私のコードの構成についての洞察をいただければ幸いです。 TypeScriptクラスと継承を使用するのもこれが初めてなので、初心者の間違いを予想してください。

8
Christian Todd

拡張クラスコンストラクターのこのコード

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

super(text)を呼び出すことにより、textを既存のクラスコンストラクターに直接渡します。したがって、ここでのtextは文字列であると想定されます。これは、既存のTextCellコンストラクターで宣言されている方法だからです。

ただし、StretchCellクラスのインスタンスを作成すると、文字列ではなく、TextCellパラメータにtextオブジェクトインスタンスが渡されます。これが_text.split is not a function_エラーの理由です-TextCellにはsplitというメソッドがありません。

拡張クラスコンストラクタは次のように宣言する必要があります

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

StretchCellインスタンスは次のように作成する必要があります。

_var sc = new StretchCell('abc', 1, 2);
_
6
artem