TypeScript重写ToString()

Dun*_*Luk 48 javascript overriding tostring typescript

假设我有一个Person看起来像这样的类:

class Person {
    constructor(
        public firstName: string,
        public lastName: string,
        public age: number
    ) {}
}
Run Code Online (Sandbox Code Playgroud)

是否可以覆盖toString()此类中的方法,因此我可以执行以下操作?

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

alertMessage(new Person('John', 'Smith', 20));
Run Code Online (Sandbox Code Playgroud)

这个覆盖可能看起来像这样:

public toString(): string {
    return this.firstName + ' ' + this.lastName;
}
Run Code Online (Sandbox Code Playgroud)

编辑:这实际上有效.请参阅下面的答案了解详情

Nyp*_*pan 37

覆盖的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)
Run Code Online (Sandbox Code Playgroud)

有时可能会出现问题的是,无法访问toString父类:

console.log("" + (new Bar() as Foo));
Run Code Online (Sandbox Code Playgroud)

将在Bar上运行toString,而不是在Foo上运行.

  • 是的,使用 `t() : =>` 确保 `this` 将是您在 toString 覆盖中所期望的。您可以阅读 [箭头函数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) 以了解更多相关信息。但这里的基本区别是箭头函数不绑定自己的 this。 (2认同)

Dun*_*Luk 7

正如@Kruga所指出的那样,该示例实际上似乎在运行时JavaScript中起作用.唯一的问题是TypeScript显示类型错误.

TS2345:类型'Person'的参数不能赋值为'string'类型的参数.

要解决此消息,您必须:

  • .toString()明确打电话
  • 或者用字符串连接对象(例如`${obj}`obj + '')
  • 或使用obj as any(不推荐,因为你将失去类型安全)

  • 在这种情况下,与更“hacky”的空字符串连接相比,显式调用“toString()”对我来说似乎更像是最佳实践。 (3认同)