javascript - TypeScript แทนที่ ToString()
สมมติว่าฉันมีคลาส Person ซึ่งมีลักษณะดังนี้:
class Person {
constructor(
public firstName: string,
public lastName: string,
public age: number
) {}
}
ฉันได้แทนที่เมธอด toString ดังนี้
public toString(): string {
return this.firstName + ' ' + this.lastName;
}
ตอนนี้ฉันคาดว่าจะสามารถทำสิ่งต่อไปนี้ได้ ซึ่งใช้งานได้ในเวลารันไทม์:
function alertMessage(message: string) {
alert(message);
}
alertMessage(new Person('John', 'Smith', 20));
แต่สิ่งนี้ยังทำให้ฉันได้รับข้อผิดพลาดนี้:
TS2345: อาร์กิวเมนต์ของชนิด 'Person' ไม่สามารถกำหนดค่าให้กับพารามิเตอร์ชนิด 'string' ได้
ฉันจะกำหนด Person ให้กับอาร์กิวเมนต์ string ตัวนี้ได้อย่างไร?
คำตอบ #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 กับ Bar ไม่ใช่กับ Foo
คำตอบ #2
ตามที่ @Kruga ชี้ให้เห็น ตัวอย่างนี้ดูเหมือนจะทำงานได้จริงใน JavaScript ตอนรันไทม์ ปัญหาเดียวคือ TypeScript แสดงข้อผิดพลาดของประเภท
TS2345: อาร์กิวเมนต์ประเภท 'Person' ไม่สามารถกำหนดค่าให้กับพารามิเตอร์ประเภท 'string' ได้
ในการแก้ไขข้อความนี้ คุณต้องทำอย่างใดอย่างหนึ่ง:
- เรียกใช้
.toString()อย่างชัดเจน - หรือรวมวัตถุกับสตริง (เช่น
`${obj}`หรือobj + '') - หรือใช้
obj as any(ไม่แนะนำเพราะคุณจะสูญเสียความปลอดภัยของประเภท)
