TypeScript - เมธอดโอเวอร์โหลดที่มีโอเปอเรเตอร์สเปรดไม่ถูกจดจำ
ฉันมีคำจำกัดความของคลาสดังต่อไปนี้:
class Test {
a(msg: string): string;
a(msg: string, ...args: unknown[]): string | { msg: string, args: unknown[]} {
if (args) {
return { msg: msg, args: args };
}
return msg;
}
}
อย่างไรก็ตาม ผมจะได้รับข้อผิดพลาดในการคอมไพล์หากผมทำแบบนี้:
new Test().a("test", "a", 1, 2, 3);
"คาดว่าจะมี 1 อาร์กิวเมนต์ แต่ได้ 5"
ฉันจะโอเวอร์โหลดเมธอดนี้อย่างถูกต้องเพื่อให้มีประเภทค่าที่ส่งกลับต่างกันสำหรับลายเซ็นต่าง ๆ ได้อย่างไร?
คำตอบ #1
การใช้งานฟังก์ชันไม่ใช่ส่วนหนึ่งของการโอเวอร์โหลดทั้งหมดที่มีอยู่ แทนที่จะเป็นเช่นนั้นคุณสามารถเขียนได้ดังนี้:
class Test {
a(msg: string): string; // overload 1
a(msg: string, ...args: unknown[]): { msg: string, args: unknown[] } // overload2
a(msg: string, ...args: unknown[]): string | { msg: string, args: unknown[] } { // impl
// ...
}
}
new Test().a("test", "a", 1, 2, 3); // { msg: string; args: unknown[]; }
new Test().a("test") // string
ตัวอย่างสนามเด็กเล่น
คำตอบ #2
TypeScript ไม่สนับสนุนการโอเวอร์โหลดฟังก์ชันด้วยจำนวนพารามิเตอร์ที่แตกต่างกัน
เอกสารระบุว่า:
TypeScript มีแนวคิดของการโอเวอร์โหลดฟังก์ชัน คุณสามารถมีฟังก์ชันหลายฟังก์ชันที่มีชื่อเดียวกันแต่มีชนิดของพารามิเตอร์และชนิดของค่าที่ส่งกลับต่างกัน อย่างไรก็ตาม จำนวนพารามิเตอร์ควรจะเท่ากัน
[...] การโอเวอร์โหลดฟังก์ชันที่มีจำนวนและชนิดของพารามิเตอร์ต่างกันแต่มีชื่อเดียวกันไม่สามารถทำได้
เคล็ดลับหนึ่งในการทำให้สิ่งที่คุณพยายามทำสำเร็จอาจเป็นสิ่งนี้
interface ReturnA {
msg: string;
args: any[];
}
class Test {
a(msg: string, ...args: never[]): string;
a(msg: string, ...args: any[]): ReturnA
a(msg: string, ...args: any[]): string | ReturnA {
if (args) return { msg, args };
return msg;
}
}
const t = new Test();
// only 1 param returns string
const str: string = t.a(`a`);
// two or more params returns the other object type
const obj: ReturnA = t.a(`a`, `param1`);
