web-dev-qa-db-ja.com

TypeScriptオーバーライドToString()

次のようなクラスPersonがあるとします。

class Person {
    constructor(
        public firstName: string,
        public lastName: string,
        public age: number
    ) {}
}

このクラスのtoString()メソッドをオーバーライドすることは可能ですか、次のようなことができますか?

function alertMessage(message: string) {
    alert(message);
}

alertMessage(new Person('John', 'Smith', 20));

このオーバーライドは次のようになります。

public toString(): string {
    return this.firstName + ' ' + this.lastName;
}

編集:これは実際に機能します。詳細については、以下の回答を参照してください。

43
Duncan Luk

toStringをオーバーライドすると、期待どおりに動作します。

class Foo {
    private id: number = 23423;
    public toString = () : string => {
        return `Foo (id: ${this.id})`;
    }
}

class Bar extends Foo {
   private name:string = "Some name"; 
   public toString = () : string => {
        return `Bar (${this.name})`;
    }
}

let a: Foo = new Foo();
// Calling log like this will not automatically invoke toString
console.log(a); // outputs: Foo { id: 23423, toString: [Function] }

// To string will be called when concatenating strings
console.log("" + a); // outputs: Foo (id: 23423)
console.log(`${a}`); // outputs: Foo (id: 23423)

// and for overridden toString in subclass..
let b: Bar = new Bar();
console.log(b); // outputs: Bar { id: 23423, toString: [Function], name: 'Some name' }
console.log("" + b); // outputs: Bar (Some name)
console.log(`${b}`); // outputs: Bar (Some name)

// This also works as wxpected; toString is run on Bar instance. 
let c: Foo = new Bar();
console.log(c); // outputs: Bar { id: 23423, toString: [Function], name: 'Some name' }
console.log("" + c); // outputs: Bar (Some name)
console.log(`${c}`); // outputs: Bar (Some name)

ただし、問題になることがあるのは、親クラスのtoStringにアクセスできないことです。

console.log("" + (new Bar() as Foo));

FooではなくBarでtoStringを実行します。

33
Nypan

@Krugaが指摘したように、この例は実際にはランタイムJavaScriptで機能するように見えました。これに関する唯一の問題は、 TypeScriptに型エラーが表示される であることです。

TS2345:タイプ「Person」の引数は、タイプ「string」のパラメーターに割り当てることができません。

このメッセージを解決するには、次のいずれかが必要です。

  • .toString()を明示的に呼び出す
  • または、オブジェクトを文字列で連結します(例:`${obj}`またはobj + ''
  • またはobj as anyを使用します(型の安全性が失われるためお勧めしません)
6
Duncan Luk