Подтвердить что ты не робот

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

Изменить: это действительно работает. Подробнее см. Ответы ниже.

4b9b3361

Ответ 1

Переопределение 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 expected; 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));

Запустит toString в баре, а не в Foo.

Ответ 2

Как указывает @Kruga, пример действительно работает во время выполнения JavaScript. Единственная проблема заключается в том, что TypeScript показывает ошибку типа.

TS2345: Аргумент типа "Персона" нельзя назначить параметру типа "строка".

Чтобы разрешить это сообщение, необходимо:

  • Вызовите .toString() явно
  • Или объедините объект со строкой (например, '${obj}' или obj + '')
  • Или используйте obj as any (не рекомендуется, так как вы потеряете безопасность типов)